一.定义
树的重心,也可以理解成树的平衡点。
有以下三种定义:
1.以重心节点为根时,最大节点子树的节点数最小
2.以重心节点为根时,每颗子树的节点数小于总结点的一半
3.以重心节点为根时,所有节点走向根的路程最短
二.性质
1.树的重心最多有两个,且两个一定相邻
2.增加或删除一个叶节点,重心最多移动一条边
3.如果把两颗树连接起来,新树重心一定在原来两颗树的重心的路径上
4.重心与点权有关,与边权无关(边权>0,重心仍是所有节点汇聚路程最短的点)
三.代码
第一种定义求树的重心
#define N 1e5
//假设树的节点数为N,且树已经建好
vector<int>tree[N];
int siz[N];
int best= 0,center;//假设只需求一个重心
void dfs(int cur,int fa){
siz[cur] = 1;//当求有点权的树的重心时,只需要把1变为该点的权重
int big = 0;
for(int i = 0;i<tree[cur].size();i++){
int v = tree[cur][i];
if(v!=fa){
dfs(v,cur);
siz[cur]+=siz[v];
big = max(big,siz[v]);
}
}
big = max(big,N-siz[cur]);
if(big>best){
best = big;
center = cur;
}
}