标签:equal 一个 scan main ase rest image numbers points
Description
Input
Output
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
利用树形dp的思想,对节点u的子树进行遍历。和树的直径不同的是,如果子树的分割确定了,那么子树之外的节点必定在一颗树上,不需要在dfs一次。
#include "stdio.h" #include "algorithm" #include "string.h" using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 20000 + 10; bool vis[maxn]; struct edge { int to, next; } e[maxn*2]; int n, num[maxn]; int size, cur; int tot = 0; int head[maxn]; void add_edge(int u, int v) { e[tot].to = v; e[tot].next = head[u]; head[u] = tot++; } void dfs(int u) { num[u] = 0; int tr = 0; vis[u] = true; for (int i = head[u]; i != -1; i = e[i].next) { int v = e[i].to; if (vis[v]) continue; dfs(v); num[u] += num[v] + 1; tr = max(num[v] + 1, tr); } tr = max(n - num[u] - 1, tr); //剩下那棵树的大小 if (tr < size || tr == size && cur > u) { //答案还要编号节点最小 size = tr; cur = u; } } void init() { memset(vis, false, sizeof(vis)); memset(head, -1, sizeof(head)); tot = 0; size = INF; } int main(int argc, char const *argv[]) { int T; scanf("%d", &T); while (T--) { init(); scanf("%d", &n); for (int i = 0; i < n-1; i++) { int u, v; scanf("%d%d", &u, &v); add_edge(u, v); add_edge(v, u); } dfs(1); printf("%d %d\n", cur, size); } return 0; }
POJ 1655 Balancing Act[树的重心/树形dp]
标签:equal 一个 scan main ase rest image numbers points
原文地址:http://www.cnblogs.com/lututu123/p/7247542.html