1. 程式人生 > >POJ 2378 Tree Cutting 子樹統計

POJ 2378 Tree Cutting 子樹統計

poi main bool ring points ont turn -m int

題目大意:給出一棵樹。將樹中的一個節點去掉之後,這棵樹會分裂成一些聯通塊。求去掉哪些點之後。全部聯通塊的大小不超過全部節點的一半。並按順序輸出。


思路:基礎的子樹統計問題,僅僅要深搜一遍就能夠出解。這個步驟和求樹的重心非常像,是樹分治的基礎。


CODE:


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

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

int size[MAX];
bool ans[MAX];

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

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

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

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


POJ 2378 Tree Cutting 子樹統計