摘要:
题意 有两颗树,在每棵树中选择一个结点并将它们两相连使得对于新的树的任意两点的距离总和最小。 思路 设 \(sz[u]\) 表示子树 \(u\) 的大小。 显然,将两数重心连接结果最优秀(根据树的重心定义)。 对于每条边,取它两端 \(sz\) 较小的那一个点 \(u\),那么这条边贡献为 \(sz 阅读全文
摘要:
思路 对于每个连通块求出任意两点距离的最大值 \(max[u]\),然后再 \(O(n^2)\) 枚举任意两个连通块连接起来,答案就是两个连通块的最大值 \(max\) 加上中间连接的边的长度。 代码 #include <bits/stdc++.h> using namespace std; usi 阅读全文
摘要:
题意 来自洛谷: 思路 记录每个点 \(u\) 所在子树可以删去的最大的部分 \(part1\) 和次大的部分 \(part2\) 和除了 \(u\) 的子树以外的部分可以删去的最大的部分 \(up\),这些部分必须要求小于等于 \(\dfrac{n}{2}\),和找树的中心(注意不是重心)的思路差 阅读全文
摘要:
思路 从下往上处理每个子树的重心。 对于任意点 \(u\),其所在子树的中心一定在 \(u\) 和 \(ans[to]\) 之间,\(ans[to]\) 是重儿子 \(to\) 的重心结点。 对于任意一点 \(u\),其所在子树的重心深度一定不大于 \(ans[to]\)。 代码 假设一个结点 \( 阅读全文
摘要:
思路 如果一棵树有两个重心,那么从一个重心的一边切割一个点到另外一个重心即可。 如果一棵树只有一个重心,那么随意断掉一个点再恢复即可。 代码 #include <bits/stdc++.h> using namespace std; const int N = 100010; struct edge 阅读全文