题目大意:
求一颗树的所有重心;
解题思路:
树的重心的求法我在poj 1655中详细讲过,这里就不说啦,这道题目是要求求出所有的重心,因此题目中会有很多最小的最大子树结点数相同,我们只需要在求最小值的时候处理一下等于号,如果不相等,置空答案数组重新存储,如果相等,则在答案数组中顺次存储;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 50010
int cnt,head[maxn];
bool vis[maxn];
int size[maxn],dp[maxn];
int n;
struct Edge{
int to,next;
}edge[2*maxn];
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(size,0,sizeof(size));
memset(dp,0,sizeof(dp));
}
void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void dfs(int u)
{
vis[u]=true;
size[u]=1;
dp[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!vis[v])
{
dfs(v);
size[u]+=size[v];
dp[u]=max(dp[u],size[v]);
}
}
dp[u]=max(dp[u],n-size[u]);
}
void ans()
{
int t=maxn;
int print[maxn];
int cot=0;
for(int i=1;i<=n;i++)
{
if(dp[i]<t)
{
cot=0;
print[cot++]=i;
t=dp[i];
}
else if(dp[i]==t)
{
print[cot++]=i;
}
}
for(int i=0;i<cot;i++)
printf("%d ",print[i]);
printf("\n");
}
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=0;i<n-1;i++)
{
int a,b;
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dfs(1);
ans();
}
}