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
", 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
", i);
60             }
61         }
62     }
63     return 0;
64 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4660217.html