标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10229 | Accepted: 4221 |
1
7
2 6
1 2
1 4
4 5
3 7
3 1
1 2
题解:求树的重心,和删除重心后得到的最大子树的结点数。树的重心就是在这棵树上找一个结点,使得删除这个结点后形成的森林的结点个数尽量平衡(也就是说最大的子树的借点数最小)。方法:DFS
CODE:
#include <iostream> #include <cstdio> #include <cstring> #define REP(i, s, n) for(int i = s; i <= n; i ++) #define REP_(i, s, n) for(int i = n; i >= s; i --) #define MAX_N 20000 + 10 using namespace std; int n, u, v; struct node1{ int v, next; } E[MAX_N << 1]; struct node2{ int sum, cnt; } N[MAX_N]; int head[MAX_N], top = 0; void add(int u, int v){ E[++ top].v = v; E[top].next = head[u]; head[u] = top; } int DFS(int x, int last){ N[x].sum = 1; N[x].cnt = 0; for(int i = head[x]; i; i = E[i].next){ if(E[i].v != last){ int t = DFS(E[i].v, x); N[x].sum += t; N[x].cnt = max(N[x].cnt, t); } } return N[x].sum; } int main(){ int T; scanf("%d", &T); while(T --){ top = 0; memset(head, 0, sizeof(head)); scanf("%d", &n); REP(i, 1, n - 1){ scanf("%d%d", &u, &v); add(u, v); add(v, u); } DFS(1, 0); int ans = 99999999, num = 0; REP(i, 1, n){ N[i].cnt = max(N[i].cnt, n - N[i].sum); if(ans > N[i].cnt){ ans = N[i].cnt; num = i; } } printf("%d %d\n", num, ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/ALXPCUN/p/4565559.html