【题意】:给你一棵树,去掉一个结点后,得到的平衡值是指分开的所有子树中结点数的最大值,求去掉哪个点,平衡值最小。

【题解】:dfs一次,把无向树变成有向树。顺便统计以每个结点为根的树的结点数,记为cnt[].
               那么点u的平衡值 balance[u] = max(n - cnt[u], max(cnt[v])),其中 v 为 u 的儿子。
               最后,ans = { u | balance[u] = min(balance[])};

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 using namespace std;
 8 #define pb push_back
 9 #define maxn 20050
10 vector<int> vec[maxn];
11 int n;
12 int balance[maxn], cnt[maxn];
13 
14 void dfs(int u, int fa) {
15     int size = vec[u].size();
16     cnt[u] = 1;
17     int tmp = 0;
18     for(int i = 0; i < size; i++) {
19         int v = vec[u][i];
20         if(v == fa) continue;
21         dfs(v, u);
22         cnt[u] += cnt[v];
23         tmp = max(cnt[v], tmp);
24     }
25     balance[u] = max(tmp, n - cnt[u]); 
26 }
27 
28 int main() {
29     int T, u, v;
30     scanf("%d", &T);
31     while(T--) {
32         scanf("%d", &n);
33         for(int i = 0; i < maxn; i++) vec[i].clear();
34         for(int i = 0; i < n - 1; i++) {
35             scanf("%d%d", &u, &v);
36             vec[u].pb(v), vec[v].pb(u);
37         }
38         dfs(1, -1);
39         int ans = 1;
40         for(int i = 1; i <= n; i++) {
41             if(balance[ans] > balance[i]) ans = i;
42         }
43         cout << ans << " " << balance[ans] << endl;
44     }
45     return 0;
46 }