• POJ 2152 Fire


    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
    ",best[1]);
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    公司程序升级 win2008
    软件
    crystal 2008升级(草稿)
    crystalreportviewers12的一些修改
    Crystal Report 2008
    deep learning 相关资料 Lei
    如何打印出符合acm要求的pdf Lei
    matlab常用命令 Lei
    Wilson Interval Lei
    Perl / Shell 脚本语言 Lei
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4789796.html
Copyright © 2020-2023  润新知