| Time Limit: 2000MS | Memory Limit: 64000K | |
| Total Submissions: 1667 | Accepted: 532 | |
| Case Time Limit: 1000MS | ||
Description
Input
Output
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
Source
#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 = 40010;
const int M = 40010;
struct node
{
	int weight;
	int next;
	int to;
}edge[M << 1];
int tot, res, ans, n, m, k, root, size;
int head[N], num[N], dp[N];
bool vis[N];
int dist[N];
void addedge(int from, int to, int weight)
{
	edge[tot].weight = weight;
	edge[tot].to = to;
	edge[tot].next = head[from];
	head[from] = tot++;
}
void get_root(int u, int fa)
{
	dp[u] = 0;
	num[u] = 1;
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (v == fa || vis[v])
		{
			continue;
		}
		get_root(v, u);
		num[u] += num[v];
		dp[u] = max(dp[u], num[v]);
	}
	dp[u] = max(dp[u], size - num[u]);
	if (dp[root] > dp[u])
	{
		root = u;
	}
}
void calc_dist(int u, int d, int fa)
{
	dist[res++] = d;
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (v == fa || vis[v])
		{
			continue;
		}
		calc_dist(v, d + edge[i].weight, u);
	}
}
int calc(int u, int d)
{
	res = 0;
	calc_dist(u, d, -1);
	int ret = 0;
	sort(dist, dist + res);
	int i = 0, j = res - 1;
	while (i < j)
	{
		while (i < j && dist[i] + dist[j] > k)
		{
			j--;
		}
		ret += j - i;
		i++;
	}
	return ret;
}
void solve()
{
	ans += calc(root, 0);
	vis[root] = 1;
	for (int i = head[root]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (vis[v])
		{
			continue;
		}
		ans -= calc(v, edge[i].weight);
		root = 0;
		dp[0] = size = num[v];
		get_root(v, -1);
		solve();
	}
}
int main()
{
	int u, v, w;
	char dir[5];
	while (~scanf("%d%d", &n, &m))
	{ 
		memset( head, -1, sizeof(head) );
		memset ( num, 0, sizeof(num) );
		memset ( vis, 0, sizeof(vis) );
		tot = 0;
		ans = 0;
		root = 0;
		for (int i = 0; i < m; ++i)
		{
			scanf("%d%d%d%s", &u, &v, &w, dir);
			addedge(u, v, w);
			addedge(v, u, w);
		}
		scanf("%d", &k);
		dp[0] = size = n;
		get_root(1, -1);
		solve();
		printf("%d\n", ans);
	}
	return 0;
}原文地址:http://blog.csdn.net/guard_mine/article/details/40819379