POJ 2152 Fire

POJ 2152 Fire

Description

Country Z has N cities, which are numbered from 1 to N. Cities are connected by highways, and there is exact one path between two different cities. Recently country Z often caught fire, so the government decided to build some firehouses in some cities. Build a firehouse in city K cost W(K). W for different cities may be different. If there is not firehouse in city K, the distance between it and the nearest city which has a firehouse, can’t be more than D(K). D for different cities also may be different. To save money, the government wants you to calculate the minimum cost to build firehouses.

Input

The first line of input contains a single integer T representing the number of test cases. The following T blocks each represents a test case.

The first line of each block contains an integer N (1 < N <= 1000). The second line contains N numbers separated by one or more blanks. The I-th number means W(I) (0 < W(I) <= 10000). The third line contains N numbers separated by one or more blanks. The I-th number means D(I) (0 <= D(I) <= 10000). The following N-1 lines each contains three integers u, v, L (1 <= u, v <= N,0 < L <= 1000), which means there is a highway between city u and v of length L.

Output

For each test case output the minimum cost on a single line.

Sample Input

5
5
1 1 1 1 1
1 1 1 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5
1 1 1 1 1
2 1 1 1 2
1 2 1
2 3 1
3 4 1
4 5 1
5
1 1 3 1 1
2 1 1 1 2
1 2 1
2 3 1
3 4 1
4 5 1
4
2 1 1 1
3 4 3 2
1 2 3
1 3 3
1 4 2
4
4 1 1 1
3 4 3 2
1 2 3
1 3 3
1 4 2

Sample Output

2
1
2
2
3

Source

POJ Monthly,Lou Tiancheng

Solution

枚舉圖中的每一個點,用與其相連的點更新二者之間的距離,如果存在距離滿足題目要求,那麼就可以考慮在那個點修建消防站,然後遞推+遞歸的更新即可……

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
#include <queue>
#define L 1010
#define inf 99999999
#define LL long long
using namespace std;

struct node {
  int nxt, to, d;
} e[L << 1];
int n, w[L], d[L], u, v, z, head[L], cnt, dis[L], best[L], f[L][L], T;

inline void add(int u, int v, int z) {
  e[++cnt].nxt = head[u], e[cnt].to = v, e[cnt].d = z, head[u] = cnt;
}

inline void dist(int x) {
  for (int i = head[x]; i; i = e[i].nxt) {
    int u = e[i].to;
    if (dis[u] != -1) continue;
    dis[u] = dis[x] + e[i].d;
    dist(u);
  }
}

inline void dfs(int x, int fa) {
  for (int i = head[x]; i; i = e[i].nxt) {
    int u = e[i].to;
    if (u == fa) continue;
    dfs(u, x);
  }
  for (int i = 1; i <= n; ++i) dis[i] = -1;
  dis[x] = 0;
  dist(x); best[x] = inf;
  for (int i = 1; i <= n; ++i) f[x][i] = inf;
  for (int i = 1; i <= n; ++i)
    if (dis[i] <= d[x]) {
      f[x][i] = w[i];
      for (int j = head[x]; j; j = e[j].nxt) {
	int u = e[j].to;
	if (u == fa) continue;
	f[x][i] += min(best[u], f[u][i] - w[i]);
      }
      best[x] = min(best[x], f[x][i]);
    }
}

int main() {
  freopen("POJ2152.in", "r", stdin);
  freopen("POJ2152.out", "w", stdout);
  scanf("%d", &T);
  while (T--) {
    memset(w, 0, sizeof(w));
    memset(d, 0, sizeof(d));
    memset(head, 0, sizeof(head));
    memset(best, 0, sizeof(best));
    cnt = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
    for (int i = 1; i <= n; ++i) scanf("%d", &d[i]);
    for (int i = 1; i < n; ++i) {
      scanf("%d %d %d", &u, &v, &z);
      add(u, v, z), add(v, u, z);
    }
    dfs(1, 0);
    printf("%d\n", best[1]);
  }
  return 0;
}

Summary

注意是多組數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章