hdu 4276 The Ghost Blows Light (树形dp)

题意:n个点每个点有点权表示宝物的价值。n-1条边,边权表示走这条边需要花的时间。

如果T时间内不能从1走到n,那么就输出字符串。如果能走出,问在T时间内走出能获得的

最大价值。


分析:

先找到1-n的最短路径,并且计算走这条最短路径所需的时间(最短时间)time1,将路径上的边权置0。

如果time1已经超过了T,说明它不能在T时间内走出来。

如果time1<T,那么将剩余的时间看成背包容积,进行树上背包。

dp[i][j]表示从i点出发回到i点,用了时间j获得的最大价值。

dp[s][j]=max(dp[s][j],dp[s][j-k-tmp]+dp[vv][k]  (vv为s的儿子)

最短路径上的边只经过一次,其他的边要经过两次。tmp=edge*2;


#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

int dp[110][510],head[110],v[110];
int T,tot,n,time1;

struct node
{
    int val,to;
    int next;
}edge[220];

int maxx(int a,int b)
{
    return a>b?a:b;
}

void init()
{
    memset(dp,0,sizeof(dp));
    memset(head,-1,sizeof(head));
    tot=0;
}

void add(int a,int b,int c)
{
    edge[tot].to=b;
    edge[tot].val=c;
    edge[tot].next=head[a];
    head[a]=tot++;
    edge[tot].to=a;
    edge[tot].val=c;
    edge[tot].next=head[b];
    head[b]=tot++;
}

bool dfs1(int u,int pre)
{
    if(u==n) return true;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        if(dfs1(v,u))
        {
            time1+=edge[i].val;
            edge[i].val=0;
            return true;
        }
    }
    return false;
}

void dfs2(int u,int pre)
{
    for(int i=T;i>=0;i--)
        dp[u][i]+=v[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int vv=edge[i].to;
        if(vv==pre) continue;
        dfs2(vv,u);
        int tmp=edge[i].val*2;
        for(int j=T;j>=tmp;j--)
        {
            for(int k=0;k<=j-tmp;k++)
                dp[u][j]=maxx(dp[u][j],dp[vv][k]+dp[u][j-k-tmp]);
        }
    }
}

int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&T)!=EOF)
    {
        init();
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&v[i]);
        time1=0;
        dfs1(1,-1);
        if(time1>T)
        {
            printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
            continue;
        }
        T-=time1;
        dfs2(1,-1);
        printf("%d\n",dp[1][T]);
    }
    return 0;
}



hdu 4276 The Ghost Blows Light (树形dp)

上一篇:spring + hibernate + annotation 简单整合


下一篇:POJ 3694 双连通缩点+LCA+并查集