树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡.
处理处每个节点的孩子有几个,和树的大小就好了。
#include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 using namespace std; const int MAXN = 20010; struct node { int to; int v; int next; }edge[MAXN*2]; int p,len; int num[MAXN]; int vis[MAXN],pre[MAXN],ind,n; int siz[MAXN];//the size of the tree int h[MAXN];//the maxnum of subtree int way; void add(int x,int y) { edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind ++; } void dfs1(int rt) { int i; vis[rt] = 1; siz[rt] = 1; for(i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(!vis[t]){ dfs1(t); siz[rt] += siz[t]; h[rt] = max(h[rt],siz[t]); } } } int main() { #ifndef ONLINE_JUDGE freopen("data.txt","r",stdin); #endif int i,j,t; scanf("%d",&t); while(t--) { scanf("%d",&n); ind = 1; memset(pre,-1,sizeof(pre)); for(i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } memset(vis,0,sizeof(vis)); memset(siz,0,sizeof(siz)); memset(h,0,sizeof(h)); dfs1(1); int ans = INF; int f; for(i=1; i<=n; i++){ int temp = max(h[i],n-siz[i]); if(ans > temp){ ans = temp; f = i; } } //cout<<siz[1]<<endl; cout<<f<<" "<<ans<<endl; } }