POJ 2152 Fire

题目传送门

题目翻译:

描述

Z国有N个城市,编号从1到N。城市之间通过高速公路相连,并且两个不同城市之间只有一条路径。Z国最近经常起火,因此*决定在一些城市建造一些消防站。在城市K成本W(K)中建立一个消防站。不同城市的W可能不同。如果城市K中没有消防站,那么它与最近的拥有消防站的城市之间的距离不能超过D(K)。不同城市的D也可能不同。为了省钱,*希望您计算建造消防站的最低费用。

输入值

输入的第一行包含一个表示测试用例数量的整数T。接下来的T块分别代表一个测试案例。 

每个块的第一行包含一个整数N(1 <N <= 1000)。第二行包含由一个或多个空格分隔的N个数字。第I个数字表示W(I)(0 <W(I)<= 10000)。第三行包含由一个或多个空格分隔的N个数字。第I个数字表示D(I)(0 <= D(I)<= 10000)。接下来的N-1行分别包含三个整数u,v,L(1 <= u,v <= N,0 <L <= 1000),这意味着在城市u和v之间有一条长度为L的高速公路。 

输出量

对于每个测试用例,单行输出的最低成本。

样本输入

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

样本输出

2
1
2
2
3

解题思路:

实在太复杂,不会描述,看大佬博客https://www.cnblogs.com/qzqzgfy/p/5553912.html

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int best[1001],dist[1001],t,w[1001],n,f[1001][1001],d[1001],head[1001],tot;
 9 struct kkk {
10     int to,v,next;
11 }e[2001];
12 
13 inline void add(int x,int y,int z) {
14     e[++tot].to = y;
15     e[tot].v = z;
16     e[tot].next = head[x];
17     head[x] = tot;
18 }
19 
20 inline void Distance(int root) {
21     for(int i = head[root];i != 0; i = e[i].next) {
22         int u = e[i].to;
23         if(dist[u] != -1) continue;
24         dist[u] = dist[root] + e[i].v;
25         Distance(u);    
26     }
27 }
28 
29 inline void dfs(int root,int fa) {
30     for(int i = head[root];i != 0; i = e[i].next) {
31         int u = e[i].to;
32         if(fa == u) continue;
33         dfs(u,root);
34     }
35     for(int i = 1;i <= n; i++)
36         dist[i] = -1;//为了不让自己更新自己,对答案无影响 
37     dist[root] = 0;
38     Distance(root);
39     best[root] = 0x3f3f3f3f3f;
40     for(int i = 1;i <= n; i++) f[root][i] = 0x3f3f3f3f;
41     for(int i = 1;i <= n; i++)
42         if(dist[i] <= d[root]) {
43             f[root][i] = w[i];
44             for(int j = head[root];j != 0; j = e[j].next) {
45                 int u = e[j].to;
46                 if(u == fa) continue;
47                 f[root][i] += min(best[u],f[u][i] - w[i]);
48             }
49             best[root] = min(best[root],f[root][i]);
50         }
51 }
52 
53 int main() {
54     scanf("%d",&t);
55     while(t--) {
56         memset(head,0,sizeof(head));
57         tot = 0;
58         scanf("%d",&n);
59         for(int i = 1;i <= n; i++)    
60             scanf("%d",&w[i]);
61         for(int i = 1;i <= n; i++)
62             scanf("%d",&d[i]);
63         for(int i = 1;i < n; i++) {
64             int x,y,z;
65             scanf("%d%d%d",&x,&y,&z);
66             add(x,y,z);
67             add(y,x,z);
68         }
69         dfs(1,-1);
70         printf("%d\n",best[1]);
71     }
72     return 0;
73 }
上一篇:CF388C Fox and Card Game


下一篇:零和博弈?