| 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;
}原文地址:http://blog.csdn.net/guard_mine/article/details/40744803