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\n", ff[1]);

	}



	fclose(stdin);

	fclose(stdout);

	return 0;

}

 

你可能感兴趣的:(poj)