1. 程式人生 > >Little Zu Chongzhi's Triangles HDU

Little Zu Chongzhi's Triangles HDU

狀壓搜尋加剪枝。

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N = 10009;
struct node{ 
	int v, l;
	node() {};
	node(int _v, int _l):v(_v),l(_l) {};
};
vector<node>Tree[N];

int n, k, size, s[N], f[N], root, deep[N], ans;
vector<int>dep;
bool used[N];
int x, y, z;
void get_root(int now, int fa)
{
	s[now] = 1;
	f[now] = 0;
	for (int i = 0; i < Tree[now].size(); i++) {
		int u = Tree[now][i].v;
		if (u != fa && !used[u]) {
			get_root(u, now);
			s[now] += s[u];
			f[now] = max(f[now], s[u]);
		}
	}
	f[now] = max(f[now], size - s[now]);
	if (f[now] < f[root]) root = now;
}
void get_dep(int now, int fa) 
{
	dep.push_back(deep[now]);
	for (int i = 0; i < Tree[now].size(); i++) {
		int u = Tree[now][i].v;
		if (u !=  fa && ! used[u]) {
			deep[u] = deep[now] + Tree[now][i].l;
			get_dep(u, now);
		}
	}
}

int calc(int now, int init)
{
	dep.clear();
	deep[now] = init;
	get_dep(now, 0);
	sort(dep.begin(), dep.end());
	int ret = 0;
	for (int l = 0, r = dep.size()-1; l < r;) {
		if (dep[l] + dep[r] <= k) ret += r-l++;
		else r--;
	}
	return ret;
}
void work(int now) 
{
	ans += calc(now, 0);
	used[now] =true;
	for (int i = 0; i < Tree[now].size(); i++) {
		int u = Tree[now][i].v;
		if (!used[u]) {
			ans -= calc(u, Tree[now][i].l);
			f[0] = size = s[u];
			get_root(u, root = 0);
			work(root);
		}
	}

}
int main()
{

	while (scanf("%d%d", &n, &k) != EOF) {
		if (n == 0 && k == 0) break;
		memset(used, 0, sizeof(used));
		for (int i = 1; i <= n; i++) Tree[i].clear();
		for (int i = 1; i < n; i++) {
			scanf("%d%d%d", &x, &y, &z);
			Tree[x].push_back(node(y, z));
			Tree[y].push_back(node(x, z));

		}
		f[0] = size = n;
		get_root(1, root = 0);
		ans = 0;
		work(root);
		printf("%d\n", ans);
		  
	}
	return 0;
	
}