求树的重心,如果有多个,输出编号最小的。
在树形dp题单看到了poj 1741 Tree,只会暴力搜索,不会别的办法。就搜题解,发现这是个树分治啊,怎么会在树形dp里?求解过程中涉及到了求树的重心,不会求,百度,才发现原来树形dp在求树的重心这里
树的直径、树的重心与树的点分治:http://www.cnblogs.com/zinthos/p/3899075.html
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN = 20010;
const int MAXM = 40020;
struct Edge
{
int to,next;
}edge[MAXM];
int tot;
int head[MAXN];
int son[MAXN];
int N;
int ans1,ans2;
void init()
{
tot = 0;
memset(son,0,sizeof(son));
memset(head,-1,sizeof(head));
}
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u, int fa)
{
son[u] = 1;
int res = 0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v == fa) continue;
dfs(v,u);
son[u] += son[v];
res = max(res,son[v]);
}
res = max(res,N-son[u]);
if(res < ans2)
{
ans2 = res;
ans1 = u;
}
else if(res == ans2 && u < ans1)
ans1 = u;
}
int main()
{
int T,n,a,b;
scanf("%d",&T);
while(T--)
{
ans2 = MAXN;
init();
scanf("%d",&n);
N = n;
for(int i = 0; i < n-1; ++i)
{
scanf("%d %d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dfs(1,-1);
printf("%d %d\n",ans1,ans2);
}
return 0;
}