题意:给出一颗n(n<=2000)个结点的树,删除其中的一个结点,会形成一棵树,或者多棵树,定义删除任意一个结点的平衡度为最大的那棵树的结点个数,问删除哪个结点后,可以让平衡度最小,即求树的重心:
定义num数组记录以当前结点为根的子树元素个数,ans数组记录删除该节点后的平衡度
#include"stdio.h" #include"string.h" #include"stdlib.h" #include"algorithm" #include"iostream" #define M 20009 using namespace std; struct node { int u,v,next; }edge[M*2]; int t,num[M],head[M],ans[M],n; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edge[t].u=u; edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } void dfs(int u,int f) { num[u]=1; ans[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==f)continue; dfs(v,u); num[u]+=num[v]; ans[u]=max(ans[u],num[v]); ans[v]=max(ans[v],n-num[v]); } } int main() { int T,i; scanf("%d",&T); while(T--) { scanf("%d",&n); init(); for(i=1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } dfs(1,-1); int id=1; for(i=1;i<=n;i++) if(ans[id]>ans[i]) id=i; printf("%d %d ",id,ans[id]); } }