HDU 4276 The Ghost Blows Light

把1~N的路径处理出来,算出需要的时间,如果时间不够就直接挂了,时间多的话就可以去用这些时间去拿别的物品了。

  对1~N这条路径上的所有点做一遍树形背包,注意背包时不要背到这条路径上的点,否则就重复计算了。最后再将路径上的点用背包合并即可。

 

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <algorithm>
using namespace std;


const int N=110;
const int E=N<<1;
const int MAXT=510;


int v[N],mark[N];
int dp[N][MAXT];
int n,t;


struct Edge{
    int to;
    int time;
    int next;
    int cost() const {
        return mark[to]?0:time*2;
    }
};

int head[N],cnt;
Edge edge[E];

void addedge(int s,int e,int time){
    ++cnt;
    edge[cnt].to=e;
    edge[cnt].time=time;
    edge[cnt].next=head[s];
    head[s]=cnt;
}


int dfs_edge(int x,int from=-1) {
    if(x==n) {
        return 0;
    }
    for(int i=head[x];i;i=edge[i].next) if(edge[i].to!=from) {
        int val;
        if((val=dfs_edge(edge[i].to,x))!=-1) {
            mark[edge[i].to]=1;
            return val+edge[i].time;
        }
    }
    return -1;
}

void dfs_dp(int x,int C,int from=-1) {
    if(C<=0) return;
    if(from==-1) {
        for(int i=0;i<=C;i++) dp[x][i]=v[x];
    }
    for(int i=head[x];i;i=edge[i].next) if(edge[i].to!=from) {
        int son=edge[i].to;
        int cost=edge[i].cost();
        for(int i=0;i<=C-cost;i++) dp[son][i]=dp[x][i]+v[son];
        dfs_dp(son,C-cost,x);
        for(int k=cost;k<=C;k++) {
            dp[x][k]=max(dp[x][k],dp[son][k-cost]);
        }
    }
}

void print() {

    for(int i=1;i<=n;i++) {
        for(int j=0;j<=t;j++) printf(" %d",dp[i][j]);
        putchar('\n');
    }

}


int main() {
    while(scanf("%d%d",&n,&t)!=EOF) {

        memset(head,0,sizeof(head));
        cnt=0;

        for(int i=0;i<n-1;i++) {
            int s,e,time;
            scanf("%d%d%d",&s,&e,&time);
            addedge(s,e,time);
            addedge(e,s,time);
        }
        for(int i=1;i<=n;i++) scanf("%d",&v[i]);
        memset(dp,0xbf,sizeof(dp));
        memset(mark,0,sizeof(mark));
        mark[1]=mark[n]=1;
        int dec=dfs_edge(1);
        dfs_dp(n,t-dec);
        int ans=-1;
        for(int i=0;i<=t;i++) ans=max(ans,dp[n][i]);
        if(ans==-1) printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
        else printf("%d\n",ans);

    }
    return 0;
}
posted @ 2012-09-10 23:28  编程菜菜  阅读(312)  评论(0编辑  收藏  举报