Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9143 | Accepted: 3797 |
Description
Input
Output
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
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 = 20010; const int inf = 0x3f3f3f3f; int n; struct node { int next; int to; }edge[N << 1]; 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 t; int u, v; scanf("%d", &t); while (t--) { 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, id; for (int i = 1; i <= n; ++i) { if (ans > dp[i]) { ans = dp[i]; id = i; } } printf("%d %d\n", id, ans); } return 0; }
原文地址:http://blog.csdn.net/guard_mine/article/details/40738579