1. 程式人生 > >poj1655 Balancing Act(找樹的重心)

poj1655 Balancing Act(找樹的重心)

define div net 題意 style 相同 樹形dp mem 得到

Balancing Act

POJ - 1655

題意:給定一棵樹,求樹的重心的編號以及重心刪除後得到的最大子樹的節點個數size,如果size相同就選取編號最小的.

/*
    找樹的重心可以用樹形dp或者dfs,這裏我用的dfs
    基本方法就是隨便設定一個根節點,然後找出這個節點的子樹大小(包括這個節點),然後總點數減去子樹的大小就是向父親節點走去的點數,使這幾部分的最大值最小
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define
maxn 20010 using namespace std; int T,n,head[maxn],num,root,son[maxn],f[maxn]; struct node{ int to,pre; }e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } void getroot(int x,int fa){ son[x]=1; for(int i=head[x];i;i=e[i].pre){
int to=e[i].to; if(to==fa)continue; getroot(to,x); son[x]+=son[to]; f[x]=max(f[x],son[to]); } f[x]=max(f[x],n-son[x]); if(f[x]<f[root])root=x; } int main(){ scanf("%d",&T); while(T--){ root=0; memset(f,0,sizeof(f));f[root]=0x7fffffff
; memset(son,0,sizeof(son)); memset(head,0,sizeof(head));num=0; memset(e,0,sizeof(e)); scanf("%d",&n); int x,y; for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); Insert(x,y);Insert(y,x); } getroot(1,0); printf("%d %d\n",root,f[root]); } }

poj1655 Balancing Act(找樹的重心)