Time Limit: 2000MS | Memory Limit: 64000K | |
Total Submissions: 1660 | Accepted: 528 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S 10
Sample Output
5
Hint
Source
/* 定义dp[i]为去掉i结点,剩下的树里,结点最多的那颗树的结点数。 可分为2类情况。 1、由于i结点的儿子结点都成了一棵树的根节点,所以dp[i] = (i的每个儿子所拥有的结点数,的最大值)。 2、而另一种情况就是剩下的那棵树,所以dp[i] = N-num[i]。 其中num[i]表示以i为根的树的所有结点数,可以dfs求出。 */ #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <vector> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 50010; const int inf = 0x3f3f3f3f; int n; struct node { int next; int to; }edge[N << 1]; int zhonxin[N]; int head[N]; int dp[N]; int num[N]; int tot; bool vis[N]; int dist[N]; void addedge(int from, int to) { edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } int dfs(int u) { vis[u] = 1; num[u] = 1; for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (!vis[v]) { num[u] += dfs(v); } } return num[u]; } void DP(int u) { vis[u] = 1; for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (vis[v]) { dp[u] = max(dp[u], n - num[u]); } else { dp[u] = max(dp[u], num[v]); DP(v); } } } int main() { int u, v; while (~scanf("%d", &n)) { memset ( head, -1, sizeof(head) ); memset ( num, 0, sizeof(num) ); memset ( vis, 0, sizeof(vis) ); memset ( dp, 0, sizeof(dp) ); tot = 0; for (int i = 0; i < n - 1; ++i) { scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } dfs(1); memset ( vis, 0, sizeof(vis) ); DP(1); int ans = inf; for (int i = 1; i <= n; ++i) { if (ans > dp[i]) { ans = dp[i]; } } int res = 0; for (int i = 1; i <= n; ++i) { if (ans == dp[i]) { zhonxin[res++] = i; } } if (ans > n / 2) { printf("NONE\n"); continue; } for (int i = 0; i < res; ++i) { printf("%d\n", zhonxin[i]); } } return 0; }