poj2152 Fire

好难啊,我弱爆了。

题解看陈启峰的论文。。。

/**
 * Problem:POJ2152
 * Author:Shun Yao
 * Time:2013.9.2
 * Result:Accepted
 * Memo:TreeDP
 */

#include <cstring>
#include <cstdio>
#include <climits>

#define MAXN 1010
#define inf LONG_MAX

long n, w[MAXN], d[MAXN], f[MAXN][MAXN], ff[MAXN], dist[MAXN];

long gtot;
class Edge {
public:
	long v, w;
	Edge *next;
	Edge() {}
	~Edge() {}
	Edge(long V, long W, Edge *ne) : v(V), w(W), next(ne) {}
} *g[MAXN], gg[MAXN << 1];

void add(long x, long y, long w) {
	g[x] = &(gg[gtot++] = Edge(y, w, g[x]));
	g[y] = &(gg[gtot++] = Edge(x, w, g[y]));		 
}

long min(long x, long y) {
	return x < y ? x : y;
}

void dis(long x) {
	Edge *e;
	for (e = g[x]; e; e = e->next)
		if (dist[e->v] == -1) {
			dist[e->v] = dist[x] + e->w;
			dis(e->v);
		}
}

void dfs(long x, long pa) {
	long i;
	Edge *e;
	for (e = g[x]; e; e = e->next)
		if (e->v != pa)
			dfs(e->v, x);
	memset(dist, -1, sizeof dist);
	dist[x] = 0;
	ff[x] = inf;
	dis(x);
	for (i = 1; i <= n; ++i)
		if (dist[i] > d[x])
			f[x][i] = inf;
		else {
			f[x][i] = w[i];
			for (e = g[x]; e; e = e->next)
				if (e->v != pa)
					f[x][i] += min(ff[e->v], f[e->v][i] - w[i]);
			ff[x] = min(ff[x], f[x][i]);
		}
}

int main() {
	static long T, i, j, u, v, l;
	
#ifndef ONLINE_JUDGE
	freopen("poj2152.in", "r", stdin);
	freopen("poj2152.out", "w", stdout);
#endif

	scanf("%ld", &T);
	while (T--) {
		scanf("%ld", &n);
		for (i = 1; i <= n; ++i)
			scanf("%ld", w + i);
		for (i = 1; i <= n; ++i)
			scanf("%ld", d + i);
		gtot = 0;
		for (i = 1; i <= n; ++i)
			g[i] = 0;
		for (i = 1; i < n; ++i) {
			scanf("%ld%ld%ld", &u, &v, &l);
			add(u, v, l);
		}
		dfs(1, 0);
		printf("%ld
", ff[1]);
	}

	fclose(stdin);
	fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/hsuppr/p/3296131.html