POJ 1655 Balancing Act 焦点树

标题效果:鉴于一棵树。除去一个点之后,这棵树将成为一些中国联通的块。之后该点通过寻求取消最低形成块的最大数目。


思维:树DP思维。通过为每个子树尺寸的根节点深搜索确定。之后该节点然后除去,,还有剩下的部分。求一下这些块中数目的最大值。就是去掉这个点时的ans。然后更新总的ans。

这个题事实上就是树的重心。


CODE:


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 20010
using namespace std;

int cases;
int points;
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1];

int p_ans,ans;

inline void Initialize();
inline void Add(int x,int y);
int DFS(int x,int last);

int main()
{
	for(cin >> cases;cases; --cases) {
		scanf("%d",&points);
		Initialize();
		for(int x,y,i = 1;i < points; ++i) {
			scanf("%d%d",&x,&y);
			Add(x,y),Add(y,x);
		}
		DFS(1,0);
		printf("%d %d\n",p_ans,ans);
	}
	return 0;
}

inline void Initialize()
{
	ans = 0x7f7f7f7f,total = 0;
	memset(head,0,sizeof(head));
}

inline void Add(int x,int y)
{
	next[++total] = head[x];
	aim[total] = y;
	head[x] = total;
}

int DFS(int x,int last)
{
	int max_size = 0,size = 1;
	for(int i = head[x];i;i = next[i]) {
		if(aim[i] == last)	continue;
		int temp = DFS(aim[i],x);
		max_size = max(max_size,temp);
		size += temp;
	}
	max_size = max(max_size,points - size);
	if(max_size < ans)
		ans = max_size,p_ans = x;
	return size;
}


版权声明:本文博客原创文章,博客,未经同意,不得转载。

posted @ 2015-07-15 12:01  mengfanrong  阅读(142)  评论(0编辑  收藏  举报