bzoj 1131: [POI2008]Sta(DPS)

1131: [POI2008]Sta

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 1705   Solved: 640
[ Submit][ Status][ Discuss]

Description

给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

Input

给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.

Output

输出你所找到的点,如果具有多个解,请输出编号最小的那个.

Sample Input

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

Sample Output

7


默认根为1

DFS求出每个点的子树大小,以及每个点的深度,设sum为树中所有节点的深度和

然后以每个点为根的树深度和可以从相邻点O(1)转移出来,再DFS一次就好

#include<stdio.h>
#include<vector>
using namespace std;
#define LL long long
vector<int> G[1000005];
int size[1000005], dep[1000005], n, ans;
LL sum, now;
int Read()
{
	int x = 0, f = 1;
	char ch;
	ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch=='-')  f = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
		x = x*10+ch-'0', ch = getchar();
	return x*f;
}
void Sech(int u, int p, int deep)
{
	int i, v;
	size[u] = 1;
	dep[u] = deep;
	for(i=0;i<G[u].size();i++)
	{
		v = G[u][i];
		if(v==p)
			continue;
		Sech(v, u, deep+1);
		size[u] += size[v];
	}
}
void DP(int u, int p)
{
	int i, v;
	if(sum>now || sum==now && u<ans)
		now = sum, ans = u;
	for(i=0;i<G[u].size();i++)
	{
		v = G[u][i];
		if(v==p)
			continue;
		sum += n-2*size[v];
		DP(v, u);
		sum -= n-2*size[v];
	}
}
int main(void)
{
	int i, x, y;
	scanf("%d", &n);
	for(i=1;i<=n-1;i++)
	{
		x = Read(), y = Read();
		G[x].push_back(y);
		G[y].push_back(x);
	}
	Sech(1, 0, 0);
	for(i=1;i<=n;i++)
		sum += dep[i];
	DP(1, 0);
	printf("%d\n", ans);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值