POJ 1655 Balancing Act (树的重心)
2015-06-24 19:31
507 查看
题目地址:POJ 1655
树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡.
树的重心可以用树形DP快速的找出来。
代码如下:
树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡.
树的重心可以用树形DP快速的找出来。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> #include <time.h> using namespace std; #define LL __int64 #define pi acos(-1.0) //#pragma comment(linker, "/STACK:1024000000") #define root 1, n, 1 #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; const int MAXN=20000+10; struct node { int v, next; }edge[MAXN<<1]; int head[MAXN], cnt, ans, min1, n; int sum[MAXN]; void add(int u, int v) { edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } void init() { memset(head,-1,sizeof(head)); cnt=0; min1=INF; } void dfs(int u, int fa) { int max1=0, i, tot=0; sum[u]=1; for(i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa) continue ; dfs(v,u); sum[u]+=sum[v]; max1=max(max1,sum[v]); tot+=sum[v]; } max1=max(max1,n-tot-1); if(min1>max1){ min1=max1; ans=u; } } int main() { int t, u, v, i; scanf("%d",&t); while(t--){ scanf("%d",&n); init(); for(i=1;i<n;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,-1); printf("%d %d\n",ans,min1); } return 0; }