对于一个无根树,可以直接设定1为根节点(树可以以任何一个点作根)
从根dfs可以遍历以每个点为根的子树的节点个数,然后遍历每个点就是父节点-子树个数+(n-子树个数)找最小即数的重心
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+50;
int d[N];
int f[N];
int n;
struct edge{
int to,nex;
}ee[N<<1];
int num=0;
int head[N];
int siz[N];
void add1(int x,int y)
{
ee[++num]=(edge){y,head[x]};
head[x]=num;
}
void dfs1(int x)
{
int too;
siz[x]=1;
for(int i=head[x];i!=-1;i=ee[i].nex)
{
too=ee[i].to;
if(d[too])
continue;
d[too]=d[x]+1;
dfs1(too);
siz[x]+=siz[too];
}
}
void dfs(int x,int fa)
{
f[x]=f[fa]+n-2*siz[x];
for(int i=head[x];i!=-1;i=ee[i].nex)
{
if(ee[i].to==x)
continue;
dfs(ee[i].to,x);
}
}
int main ()
{
cin>>n;
int uu,vv;
memset(head,-1,sizeof(head));
for(int i=1;i<n;++i)
{
cin>>uu>>vv;
add1(uu,vv);
add1(vv,uu);
}
d[1]=1;
siz[1]=1;
dfs1(1);
for(int i=1;i<=n;++i)
{
f[1]+=d[i];
}
f[1]-=n;
for(int i=head[1];i!=-1;i=ee[i].nex)
{
dfs(ee[i].to,1);
}
int anss=INT_MAX;
for(int i=1;i<=n;++i)
{
anss=min(anss,f[i]);
}
cout<<anss;
}