zoukankan      html  css  js  c++  java
  • HDU 4276 树形dp

    The Ghost Blows Light

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3452    Accepted Submission(s): 1086


    Problem Description

    My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consists of N rooms (numbered from 1 to N) which are connected by some roads (pass each road should cost some time). There is exactly one route between any two rooms, and each room contains some treasures. Now I am located at the 1st room and the exit is located at the Nth room. 
    Suddenly, alert occurred! The tomb will topple down in T minutes, and I should reach exit room in T minutes. Human beings die in pursuit of wealth, and birds die in pursuit of food! Although it is life-threatening time, I also want to get treasure out as much as possible. Now I wonder the maximum number of treasures I can take out in T minutes.
     
    Input
    There are multiple test cases.
    The first line contains two integer N and T. (1 <= n <= 100, 0 <= T <= 500)
    Each of the next N - 1 lines contains three integers a, b, and t indicating there is a road between a and b which costs t minutes. (1<=a<=n, 1<=b<=n, a!=b, 0 <= t <= 100)
    The last line contains N integers, which Ai indicating the number of treasure in the ith room. (0 <= Ai <= 100)
     
    Output
    For each test case, output an integer indicating the maximum number of treasures I can take out in T minutes; if I cannot get out of the tomb, please output "Human beings die in pursuit of wealth, and birds die in pursuit of food!".
     
    Sample Input
    5 10
    1 2 2
    2 3 2
    2 5 3
    3 4 3
    1 2 3 4 5
     
    Sample Output
    11
     
    Source
     题意:
    n个点n-1条无向边的树,通过每条边有时间,每个点有权值,要求在T时间内从1点走到n点得到的最大价值(每点的价值只算一次)
    代码:
    //1~n点的路径是必须走的并且只走一次,先dfs处理出这条路径并把路径的边权值设为0
    //然后顺着这条路径从下到上进行树形dp即可(其他的边如果经过就要走两次)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=1009;
    int flag,sum,n,T,dp[maxn][509],head[maxn],tol,val[maxn],pre[maxn];
    struct Edge{
        int to,w,next;
    }edge[maxn*2];
    void Add(int x,int y,int z){
        edge[tol].to=y;
        edge[tol].w=z;
        edge[tol].next=head[x];
        head[x]=tol++;
    }
    void dfs1(int x,int fa,int cnt){
        pre[x]=fa;
        if(x==n){
            flag=1;
            T-=cnt;
            return;
        }
        for(int i=head[x];i!=-1;i=edge[i].next){
            int y=edge[i].to;
            if(y==fa) continue;
            dfs1(y,x,edge[i].w+cnt);
            if(flag){
                edge[i].w=0;
                return;
            }
        }
    }
    void dfs2(int x,int fa){
        for(int i=0;i<=T;i++) dp[x][i]=val[x];
        for(int i=head[x];i!=-1;i=edge[i].next){
            int y=edge[i].to;
            if(y==fa) continue;
            dfs2(y,x);
            for(int j=T;j>=2*edge[i].w;j--){
                for(int k=0;k+2*edge[i].w<=j;k++){
                    dp[x][j]=max(dp[x][j],dp[x][j-2*edge[i].w-k]+dp[y][k]);
                }
            }
        }
    }
    void solve(int x){
        sum=0;
        while(x!=0){
            sum+=val[x];
            val[x]=0;
            dfs2(x,pre[x]);
            x=pre[x];
        }
        
    }
    int main()
    {
        while(scanf("%d%d",&n,&T)==2){
            memset(head,-1,sizeof(head));
            tol=0;
            memset(pre,0,sizeof(pre));
            for(int i=1;i<n;i++){
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                Add(x,y,z);Add(y,x,z);
            }
            for(int i=1;i<=n;i++) scanf("%d",&val[i]);
            flag=0;
            dfs1(1,0,0);
            if(T<0){
                printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!
    ");
                continue;
            }
            memset(dp,0,sizeof(dp));
            solve(n);
            printf("%d
    ",sum+dp[1][T]);
        }
        return 0;
    }
  • 相关阅读:
    部署DNS正向解析-使域名和ip互相认识能够友好的访问
    部署NTP时间服务器-使时间同步
    Linux系统中常见的目录名称以及相应内容及用户管理相关文件
    systemctl常用操作
    部署NFS
    配置本地用户模式ftp服务 差个网上的
    js预解析
    jquery 三级联动
    js事件冒泡
    jquery 判断checkbox是否选中
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/6872462.html
Copyright © 2011-2022 走看看