POJ - 3107 Godfather 树的重心

题目链接:点击查看

题意:找出树的重心,如果多个按编号从小到大输出   树的重心定义:点击查看

题解:树形dp,找出孩子中最大的,n-孩子总数即为向上节点数,求个最大的即可

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=50100;
struct node{
	int to,nex;
	node(){}
	node(int to_,int nex_)
	{
		to=to_;
		nex=nex_;
	}
}e[N*2];
int n;
int head[N],len,son[N],dp[N];
int minn,num;
void addedge(int x,int y)
{
	e[len].to=y;
	e[len].nex=head[x];
	head[x]=len++;
}
void dfs(int u,int f)
{
	son[u]=1;
	int cnt=0;
	for(int i=head[u];i!=-1;i=e[i].nex)
	{
		int to=e[i].to;
		if(to==f) continue;
		dfs(to,u);
		cnt=max(cnt,son[to]);
		son[u]+=son[to]; 
	}
	cnt=max(cnt,n-son[u]);
	dp[u]=cnt;
	if(cnt<minn)
	{
		minn=cnt;
		num=1;
	}
	else if(cnt==minn)
	{
		num++;
	}
}
int main()
{
	int x,y;
	while(~scanf("%d",&n))
	{
		for(int i=0;i<=n;i++) head[i]=-1;
		len=0;
		minn=n;
		for(int i=1;i<n;i++)
		{
			scanf("%d%d",&x,&y);
			addedge(x,y);
			addedge(y,x);
		}
		dfs(1,0);
		int cnt=0;
		
		for(int i=1;i<=n;i++)
		{
			if(dp[i]==minn)
			{
				cnt++;
				printf("%d%c",i," \n"[cnt==num]);
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/88552573
今日推荐