题目传送门
题目翻译:
描述
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的高速公路。
每个块的第一行包含一个整数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 }