树的重心,就是它为根后每个子树的节点数小于等于总结点数的二分之一。
其实代码代表了全部思想
我们开始假设 1 <script type="math/tex" id="MathJax-Element-1">1</script>为根,然后看代码:
#include<vector>
#define N 1000010
vector<int>t[N];
int w[N],f[N],ans,n;
void getw(int x)
{
w[x]=1;
fr(i,0,t[x].size()-1)
if(f[x]!=t[x][i])
{
f[t[x][i]]=x;
getw(t[x][i]);
w[x]+=w[t[x][i]];
}
}//得出每个子树的大小
void getans(int x)
{
if(ans)
return;
int nex=0;
fr(i,0,t[x].size()-1)
if(f[x]!=t[x][i]&&w[t[x][i]]>(n>>1))
nex=t[x][i];//向下找,直到大小最大的子树的根节点所代表的子树大小满足重心条件
if(nex)
getans(nex);
else
ans=x;
}
int main()
{
n=read();
fr(i,1,n-1)
{
int u=read(),v=read();
t[u].push_back(v);
t[v].push_back(u);
}
getw(1);
getans(1);
printf("%d\n",ans);
return 0;
}