码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1655:Balancing Act

时间:2016-08-02 16:31:21      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

Balancing Act

题目链接:

http://poj.org/problem?id=1655

题意:

给出一棵树,求树的重心和以重心为根节点节点最多的子树的节点数,如果有多个重心输出编号较小的。

 

题解:

树的重心:找出一个节点v,以v为根,使得v的“节点最多的子树”的节点最少化

水题,随便以某个节点为根开始深搜,其中某节点v的“节点最多的子树”的节点数=min(sum[child[v]],n-∑sum[child[v]]-1)

      

代码

 
#include<stdio.h>
const int N=2e4+1;
int cnt,head[N],Ev[N*2],Enext[N*2],res1,res2;
int Abs(int x)
{
	return x>=0?x:-x;
}
void addedge(int u,int v)
{
	Ev[cnt]=v;
	Enext[cnt]=head[u];
	head[u]=cnt++;
}
int Dfs(int id,int fa,int n)
{
	int sum=0,mx=0;
	for(int i=head[id];i!=-1;i=Enext[i])
	{
		int v=Ev[i];
		if(v==fa)continue;
		int w=Dfs(v,id,n);
		sum+=w;
		if(w>mx)mx=w;
	}
	sum++;
	if(n-sum>mx)mx=n-sum;
	if(mx<res2||(mx==res2&&id<res1))
	{
		res2=mx;
		res1=id;
	}
	return sum;
}
void clean(int n)
{
	cnt=0;
	res2=n+1;
	for(int i=1;i<=n;++i)
	head[i]=-1;
}
void solve()
{
	int T,n,x,y;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		if(n==1)while(1);
		clean(n);
		for(int i=1;i<n;++i)
		{
			scanf("%d%d",&x,&y);
			addedge(x,y);
			addedge(y,x);
		}
		Dfs(1,1,n);
		printf("%d %d\n",res1,res2);
	}
}
int main()
{
	solve();
	return 0;
}

  

POJ 1655:Balancing Act

标签:

原文地址:http://www.cnblogs.com/kiuhghcsc/p/5729462.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!