POJ 1655 Balancing Act (树的重心)

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

题意:

        求树的重心(最小序号),以及去掉重心后子树节点最大是多少。(树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心

思路:

        dfs

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 const int N = 2e4 + 5;
 7 int dp[N], n;
 8 vector <int> G[N];
 9 
10 int dfs(int u, int p) {
11     dp[u] = 0;
12     int sum = 0;
13     for(int i = 0; i < G[u].size(); ++i) {
14         int v = G[u][i];
15         if(v == p)
16             continue;
17         int temp = dfs(v, u);
18         sum += temp;
19         dp[u] = max(temp, dp[u]);
20     }
21     dp[u] = max(dp[u], n - sum - 1);
22     return sum + 1;
23 }
24 
25 int main()
26 {
27     int t;
28     scanf("%d", &t);
29     while(t--) {
30         scanf("%d", &n);
31         int u, v;
32         for(int i = 1; i <= n; ++i) {
33             G[i].clear();
34         }
35         for(int i = 1; i < n; ++i) {
36             scanf("%d %d", &u, &v);
37             G[u].push_back(v);
38             G[v].push_back(u);
39         }
40         dfs(1, -1);
41         int ans = n, pos = n;
42         for(int i = n; i >= 1; --i) {
43             if(dp[i] <= ans) {
44                 ans = dp[i];
45                 pos = i;
46             }
47         }
48         printf("%d %d\n", pos, ans);
49     }
50     return 0;
51 }

 

posted @ 2016-10-11 14:11  Recoder  阅读(213)  评论(0编辑  收藏  举报