好难啊,我弱爆了。
题解看陈启峰的论文。。。
/** * 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; }