poj1655Balancing Act<DP>

链接:http://poj.org/problem?id=1655

题意: 求树的重心;

树的重心为去掉该节点使其形成的森林中的树的最大的节点数最小;

思路:对于一棵树的任意一个节点做一次DFS就能遍历整棵树, 去掉某节点时, 遍历其子树的节点个数,和为sum那么另一个子树的节点为N-sum-1; 

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 const int M=20005;
 4 int T, N, t, ans, r, x, y;
 5 int h[M*2], sum[M*2];// re[M*2];
 6 struct Edge
 7 {
 8     int v, next;
 9 }e[M*2];
10 void AE( int x, int y )//  建边 
11 {
12     e[t].v=x, e[t].next=h[y], h[y]=t++;
13 }
14 int Max( int a, int b )
15 {
16     return a>b?a:b;
17 }
18 void DFS( int s, int f ) 
19 {
20     int temp=0;
21     sum[s]=0;
22     re[s]=1;
23     for( int i=h[s]; i!=-1 ; i=e[i].next ){ // 遍历每一个节点 
24         int v=e[i].v;
25         if( v==f ) continue;
26     //    if( re[v] )continue;
27         DFS( v, s );
28         temp=Max( temp, sum[v]+1 );
29         sum[s]+=(sum[v]+1);
30     }
31     temp=Max( temp, N-sum[s]-1 );//  与剩下的一边比较 
32     if( ans>temp ){
33         ans=temp;
34         r=s;
35     }
36     
37         
38 }
39 int main( )
40 {
41     scanf( "%d", &T ); 
42     while( T -- ){
43         scanf( "%d", &N );
44         memset( h, -1, sizeof h );
45         memset( re, 0, sizeof re );
46         t=0;
47         for( int i=1; i<N; ++ i ){
48             scanf( "%d%d", &x, &y );
49             AE( x, y );
50             AE( y, x );
51         }
52         ans=1<<30;
53         DFS( 1, -1 );
54         printf( "%d %d\n", r, ans );
55     }
56     return 0;
57 }

 

posted @ 2013-01-07 20:19  淡墨æ末央  阅读(104)  评论(0编辑  收藏  举报