poj 1655 and 3107 and 2378 树形dp(树的重心问题)

简单的树形dp,顺便学习了树的重心的概念,即以该点为根的树的最大子树的结点数最少。

poj 1655:

 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 using namespace std;

 5 

 6 const int N = 20001;

 7 int head[N];

 8 int balance[N];

 9 int child[N];

10 int n, e;

11 

12 struct Edge

13 {

14     int v, next;

15 } edge[N * 2];

16 

17 void addEdge( int u, int v )

18 {

19     edge[e].v = v;

20     edge[e].next = head[u];

21     head[u] = e++;

22 }

23 

24 void dfs( int u, int fa )

25 {

26     balance[u] = 0;

27     child[u] = 1;

28     for ( int i = head[u]; i != -1; i = edge[i].next )

29     {

30         int v = edge[i].v;

31         if ( v != fa )

32         {

33             dfs( v, u );

34             balance[u] = max( balance[u], child[v] );

35             child[u] += child[v];

36         }

37     }

38     balance[u] = max( balance[u], n - child[u] );

39 }

40 

41 int main ()

42 {

43     int t;

44     scanf("%d", &t);

45     while ( t-- )

46     {

47         scanf("%d", &n);

48         e = 0;

49         memset( head, -1, sizeof(head) );

50         for ( int i = 1; i < n; i++ )

51         {

52             int u, v;

53             scanf("%d%d", &u, &v);

54             addEdge( u, v );

55             addEdge( v, u );

56         }

57         dfs( 1, -1 );

58         int ans = 1;

59         for ( int i = 2; i <= n; i++ )

60         {

61             if ( balance[i] < balance[ans] )

62             {

63                 ans = i;

64             }        

65         }

66         printf("%d %d\n", ans, balance[ans]);

67     }

68     return 0;

69 }

poj 3107:

 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 using namespace std;

 5 

 6 const int N = 50001;

 7 int head[N];

 8 int balance[N];

 9 int child[N];

10 int n, e;

11 

12 struct Edge

13 {

14     int v, next;

15 } edge[N * 2];

16 

17 void addEdge( int u, int v )

18 {

19     edge[e].v = v;

20     edge[e].next = head[u];

21     head[u] = e++;

22 }

23 

24 void dfs( int u, int fa )

25 {

26     balance[u] = 0;

27     child[u] = 1;

28     for ( int i = head[u]; i != -1; i = edge[i].next )

29     {

30         int v = edge[i].v;

31         if ( v != fa )

32         {

33             dfs( v, u );

34             balance[u] = max( balance[u], child[v] );

35             child[u] += child[v];

36         }

37     }

38     balance[u] = max( balance[u], n - child[u] );

39 }

40 

41 int main ()

42 {

43     while ( scanf("%d", &n) != EOF )    

44     {

45         e = 0;

46         memset( head, -1, sizeof(head) );

47         for ( int i = 1; i < n; i++ )

48         {

49             int u, v;

50             scanf("%d%d", &u, &v);

51             addEdge( u, v );

52             addEdge( v, u );

53         }

54         dfs( 1, -1 );

55         int minn = 1;

56         for ( int i = 2; i <= n; i++ )

57         {

58             if ( balance[i] < balance[minn] )

59             {

60                 minn = i;

61             }

62         }

63         printf("%d", minn);

64         for ( int i = minn + 1; i <= n; i++ )

65         {

66             if ( balance[i] == balance[minn] )

67             {

68                 printf(" %d", i);

69             }

70         }

71         puts("");

72     }

73     return 0;

74 }

poj 2378:

 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 using namespace std;

 5 

 6 const int N = 10001;

 7 int head[N];

 8 int balance[N];

 9 int child[N];

10 int n, e;

11 

12 struct Edge

13 {

14     int v, next;

15 } edge[N * 2];

16 

17 void addEdge( int u, int v )

18 {

19     edge[e].v = v;

20     edge[e].next = head[u];

21     head[u] = e++;

22 }

23 

24 void dfs( int u, int fa )

25 {

26     balance[u] = 0;

27     child[u] = 1;

28     for ( int i = head[u]; i != -1; i = edge[i].next )

29     {

30         int v = edge[i].v;

31         if ( v != fa )

32         {

33             dfs( v, u );

34             balance[u] = max( balance[u], child[v] );

35             child[u] += child[v];

36         }

37     }

38     balance[u] = max( balance[u], n - child[u] );

39 }

40 

41 int main ()

42 {

43     while ( scanf("%d", &n) != EOF )    

44     {

45         e = 0;

46         memset( head, -1, sizeof(head) );

47         for ( int i = 1; i < n; i++ )

48         {

49             int u, v;

50             scanf("%d%d", &u, &v);

51             addEdge( u, v );

52             addEdge( v, u );

53         }

54         dfs( 1, -1 );

55         for ( int i = 1; i <= n; i++ )

56         {

57             if ( balance[i] <= n / 2 )

58             {

59                 printf("%d\n", i);

60             }

61         }

62     }

63     return 0;

64 }

 

你可能感兴趣的:(poj)