1. 程式人生 > >【POJ 1655】Balancing Act

【POJ 1655】Balancing Act

【題目】

傳送門

Description

Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1…N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T.

For example, consider the tree:

在這裡插入圖片描述

Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.

For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.

Input

The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.

Output

For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.

Sample Input

1
7
2 6
1 2
1 4
4 5
3 7
3 1

Sample Output

1 2

【分析】

題目大意:(多組資料)給出一棵樹,求出這顆樹的重心以及重心子樹中節點數最多的子樹的節點數

樹的重心模板題

今天終於把樹的重心弄清楚了(主要是為了給點分治做鋪墊)

其實樹的重心不難,只是之前一直都沒有時間來學習它,在學點分治前終於把它補回來了


【程式碼】

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 50005
#define inf (1ll<<31ll)-1
using namespace std;
int n,t,pos,num;
int size[N],Max[N];
int first[N],v[N],next[N];
void add(int x,int y)
{
	t++;
	next[t]=first[x];
	first[x]=t;
	v[t]=y;
}
void dfs(int x,int father)
{
	int i,j;
	Max[x]=0;
	size[x]=1;
	for(i=first[x];i;i=next[i])
	{
		j=v[i];
		if(j!=father)
		{
			dfs(j,x);
			size[x]+=size[j];
			Max[x]=max(Max[x],size[j]);
		}
	}
	Max[x]=max(Max[x],n-size[x]);
	if(num>Max[x])  pos=x,num=Max[x];
}
int main()
{
	int x,y,i,cas;
	scanf("%d",&cas);
	while(cas--)
	{
		t=0,pos=0,num=inf;
		memset(first,0,sizeof(first));
		scanf("%d",&n);
		for(i=1;i<n;++i)
		{
			scanf("%d%d",&x,&y);
			add(x,y),add(y,x);
		}
		dfs(1,0);
		printf("%d %d\n",pos,num);
	}
	return 0;
}