树的重心 复习笔记
前言
没脑子选手今天模拟赛 \(\text{T1}\) 暴力发现树的重心不会求了就来看一下。
正文
计算以无根树每个点为根节点时的最大子树大小,这个值最小的点称为无根树的重心。
性质一
树的重心的最大子树大小不大于整棵树大小的一半。
性质二
树至多有两个重心。如果树有两个重心,那么它们相邻。
此时树一定有偶数个节点,且可以被划分为两个大小相等的分支,每个分支各自包含一个重心。
性质三
树中所有点到某个点的距离和中。到重心的距离和是最小的;
如果有两个重心,那么到它们的距离和一样。反过来,距离和最小的点一定是重心。
性质四
往树上增加或减少一个叶子。
如果原节点数是奇数,那么重心可能增加一个,原重心仍是重心;
如果原节点数是偶数,重心可能减少一个,另一个重心仍是重心。
性质五
把两棵树通过一条边相连得到一棵新的树,
则新的重心在较大的一棵树一侧的连接点与原重心之间的简单路径上。
如果两棵树大小一样,则重心就是两个连接点。
Code
inline void find(int now, int father) {
siz[now] = 1;
w[now] = 0;
for (int t : dis[now]) {
if (t == father) continue;
find(t, now);
siz[now] += siz[t];
w[now] = std::max(w[now], siz[t]);
}
w[now] = std::max(w[now], n - siz[now]);
if (w[now] <= n / 2)
rt.push_back(now);
}