树的重心 原题链接
#include <bits/stdc++.h>
using namespace std;
const int N=100000+10;
//因为是双向边
int h[N],e[2*N],ne[2*N],idx,ans=N;
bool b[N];//每个结点的访问标记
int n;
//加入a到b的一条边
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int dfs(int u){
b[u]=true;//标记u这个点被搜过
//size是表示将u点去除后,剩下的子树中数量的最大值;
//sum表示以u为根的子树的点的多少,初值为1,因为已经有了u这个点
int size=0,sum=1;
for (int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if (!b[j]){
int s=dfs(j); //s是以j为根节点的子树中点的数量
size=max(size,s);
sum+=s;
}
}
//n-sum表示的是减掉u为根的子树,整个树剩下的点的数量
size=max(size,n-sum);
ans=min(ans,size);
return sum;//返回的是以u为根的子树中点的数量
}
int main(){
cin>>n;
memset(h,-1,sizeof(h));
for (int i=0; i<n-1; i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1);
cout<<ans<<endl;
return 0;
}