poj1655Balancing Act

链接: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 }

 

你可能感兴趣的:(poj)