首页 > 代码库 > POJ2378——Tree Cutting

POJ2378——Tree Cutting

Distance Statistics
Time Limit: 2000MS Memory Limit: 64000K
Total Submissions: 1660 Accepted: 528
Case Time Limit: 1000MS

Description

Frustrated at the number of distance queries required to find a reasonable route for his cow marathon, FJ decides to ask queries from which he can learn more information. Specifically, he supplies an integer K (1 <= K <= 1,000,000,000) and wants to know how many pairs of farms lie at a distance at most K from each other (distance is measured in terms of the length of road required to travel from one farm to another). Please only count pairs of distinct farms (i.e. do not count pairs such as (farm #5, farm #5) in your answer).

Input

* Lines 1 ..M+1: Same input format as in "Navigation Nightmare"

* Line M+2: A single integer, K.

Output

* Line 1: The number of pairs of farms that are at a distance of at most K from each-other.

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
10

Sample Output

5

Hint

There are 5 roads with length smaller or equal than 10, namely 1-4 (3), 4-7 (2), 1-7 (5), 3-5 (7) and 3-6 (9).

Source

USACO 2004 February


求树的重心,只要判断拿掉重心以后,其余每一部分点数的最大值是否超过一半,如果超过,则输出NONE,否则输出所有的重心

 /*  
    定义dp[i]为去掉i结点,剩下的树里,结点最多的那颗树的结点数。  
    可分为2类情况。  
    1、由于i结点的儿子结点都成了一棵树的根节点,所以dp[i] = (i的每个儿子所拥有的结点数,的最大值)。  
    2、而另一种情况就是剩下的那棵树,所以dp[i] = N-num[i]。  
    其中num[i]表示以i为根的树的所有结点数,可以dfs求出。  
*/ 
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 50010;
const int inf = 0x3f3f3f3f;
int n;

struct node
{
	int next;
	int to;
}edge[N << 1];

int zhonxin[N];
int head[N];
int dp[N];
int num[N];
int tot;
bool vis[N];
int dist[N];

void addedge(int from, int to)
{
	edge[tot].to = to;
	edge[tot].next = head[from];
	head[from] = tot++;
}

int dfs(int u)
{
	vis[u] = 1;
	num[u] = 1;
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (!vis[v])
		{
			num[u] += dfs(v);
		}
	}
	return num[u];
}

void DP(int u)
{
	vis[u] = 1;
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (vis[v])
		{
			dp[u] = max(dp[u], n - num[u]);
		}
		else
		{
			dp[u] = max(dp[u], num[v]);
			DP(v);
		}
	}
}

int main()
{
	int u, v;
	while (~scanf("%d", &n))
	{
		memset ( head, -1, sizeof(head) );
		memset ( num, 0, sizeof(num) );
		memset ( vis, 0, sizeof(vis) );
		memset ( dp, 0, sizeof(dp) );
		tot = 0;
		for (int i = 0; i < n - 1; ++i)
		{
			scanf("%d%d", &u, &v);
			addedge(u, v);
			addedge(v, u);
		}
		dfs(1);
		memset ( vis, 0, sizeof(vis) );
		DP(1);
		int ans = inf;
		for (int i = 1; i <= n; ++i)
		{
			if (ans > dp[i])
			{
				ans = dp[i];
			}
		}
		int res = 0;
		for (int i = 1; i <= n; ++i)
		{
			if (ans == dp[i])
			{
				zhonxin[res++] = i;
			}
		}
		if (ans > n / 2)
		{
			printf("NONE\n");
			continue;
		}
		for (int i = 0; i < res; ++i)
		{
			printf("%d\n", zhonxin[i]);
		}
	}
	return 0;
}


POJ2378——Tree Cutting