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.
* 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,否则输出所有的重心
求树的重心,只要判断拿掉重心以后,其余每一部分点数的最大值是否超过一半,如果超过,则输出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;
}