Fire
Time Limit: 2000ms
Memory Limit: 65536KB
This problem will be judged on PKU. Original ID: 2152
64-bit integer IO format: %lld Java class name: Main
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
解题:楼教主的题目真的很难
参考这位大牛的博客
$dp[i][j]表示结点i靠j消防,best[i]表示以i为根的子树的每个节点以u内的某个节点作为负责站的最小花费$
$$best[u] = min(dp[u][i])\ i \in subtree(u)$$
$if\ dis(u,i) > d_u \ ,u 不能靠i来消防$
$if \ dis(u,i) \leq d_u,这时候u可以靠i来消防,u的儿子也可以靠i来消防,儿子也可以靠自己内部的点来消防$
$初始化条件\ dp[u][i] = dis(u,i) \leq limit[u]?cost[u]:+\infty$
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 1010; 6 const int INF = 0x3f3f3f3f; 7 struct arc{ 8 int to,w,next; 9 arc(int x = 0,int y = 0,int z = -1){ 10 to = x; 11 w = y; 12 next = z; 13 } 14 }e[maxn*2]; 15 int head[maxn],w[maxn],d[maxn],best[maxn],dis[maxn][maxn],tot,n; 16 int dp[maxn][maxn],m; 17 void add(int u,int v,int w){ 18 e[tot] = arc(v,w,head[u]); 19 head[u] = tot++; 20 } 21 void dfs(int u,int fa,int dd,int root){ 22 dis[root][u] = dd; 23 for(int i = head[u]; ~i; i = e[i].next){ 24 if(e[i].to == fa) continue; 25 dfs(e[i].to,u,dd + e[i].w,root); 26 } 27 } 28 void solve(int u,int fa){ 29 for(int i = 1; i <= n; ++i) 30 if(dis[u][i] <= d[u]) dp[u][i] = w[i]; 31 for(int i = head[u]; ~i; i = e[i].next){ 32 if(e[i].to == fa) continue; 33 solve(e[i].to,u); 34 for(int j = 1; j <= n; ++j) 35 if(dis[u][j] <= d[u]) 36 dp[u][j] += min(dp[e[i].to][j] - w[j],best[e[i].to]); 37 } 38 for(int i = 1; i <= n; ++i) best[u] = min(best[u],dp[u][i]); 39 } 40 int main(){ 41 int kase,u,v,ww; 42 scanf("%d",&kase); 43 while(kase--){ 44 memset(head,-1,sizeof head); 45 scanf("%d",&n); 46 for(int i = 1; i <= n; ++i) 47 scanf("%d",w + i); 48 for(int i = 1; i <= n; ++i) 49 scanf("%d",d + i); 50 tot = 0; 51 for(int i = 1; i < n; ++i){ 52 scanf("%d%d%d",&u,&v,&ww); 53 add(u,v,ww); 54 add(v,u,ww); 55 } 56 memset(dp,0x3f,sizeof dp); 57 memset(best,0x3f,sizeof best); 58 for(int i = 1; i <= n; ++i) dfs(i,-1,0,i); 59 solve(1,-1); 60 printf("%d\n",best[1]); 61 } 62 return 0; 63 }