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

注意是多组数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值