预处理出每个子树的大小,就可以线性判断每个点拿掉之后剩余的子树是否符合条件。

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 
 6 const int N = 10000 + 10;
 7 
 8 int n, half;
 9 vector<int> adj[N], ans;
10 int size[N];
11 
12 int cal_size(int u, int f)
13 {
14     size[u] = 1;
15     for (vector<int>::iterator it = adj[u].begin(); it != adj[u].end(); ++it)
16     {
17         if (*it != f)
18             size[u] += cal_size(*it, u);
19     }
20     return size[u];
21 }
22 
23 void dfs(int u, int f)
24 {
25     bool flag = size[0- size[u] <= half;
26     for (vector<int>::iterator it = adj[u].begin(); it != adj[u].end(); ++it)
27     {
28         if (*it != f)
29         {
30             if (size[*it] > half)
31                 flag = false;
32             dfs(*it, u);
33         }
34     }
35     if (flag)
36         ans.push_back(u + 1);
37 }
38 
39 int main()
40 {
41     scanf("%d"&n);
42     half = n / 2;
43     for (int i = 1; i < n; ++i)
44     {
45         int u, v;
46         scanf("%d%d"&u, &v);
47         --u,--v;
48         adj[u].push_back(v);
49         adj[v].push_back(u);
50     }
51     cal_size(0-1);
52     dfs(0-1);
53     sort(ans.begin(), ans.end());
54     for (vector<int>::iterator it = ans.begin(); it != ans.end(); ++it)
55         printf("%d\n"*it);
56     return 0;
57 }
58