树的重心
参考资料
简介
树的重心(centroid)是这样的节点 :删去 后,所得各连通分量的大小均不超过原树节点数的一半。重心最多有两个,且若有两个则必定相邻。
求重心用 DFS:以任意节点为根计算各子树大小 ,每个节点 的「重量」 即删去 后最大连通分量的大小。 的节点即为重心。时间复杂度 。
重心的关键性质:以重心为根,任意真子树大小均不超过 。这使得树的重心分解(点分治)成为可能。
实现
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
vector<int> G[N];
int siz[N],mx[N];
int n,ans;
void dfs(int u,int fa)
{
siz[u]=1;mx[u]=0;
for(auto v:G[u])
{
if(v==fa)continue;
dfs(v,u);
siz[u]+=siz[v];
mx[u]=max(mx[u],siz[v]);
}
mx[u]=max(mx[u],n-siz[u]);
if(mx[u]<=n/2)ans=u;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
cout<<ans<<'\n';
return 0;
}