hdu 4276 树形背包 The Ghost Blows Light

题意:在一个树状图中,每一个节点都有一个宝藏,给定起点标号为1,终点标号为n,求在特定时间内是否可以到达终点,并找出能得到的最大宝藏。

做法:参考大牛。在树的结构中任意两节点之间有且仅有一条通路。所以要得到额外宝藏时,必须折回到原路径才能走到终点。虽是如此,可是WA了许久,代码能力不足啊。

#include<stdio.h>
#include<string.h>
/*0的含义要记得
记得测试时,要拿1或者0规模的小数据,下面的错误就是在点为1 的时候出错的!!!!!*/
typedef struct
{
    int u,v,t,next;
}line;
line e[210];
int path[105],val[105],get[105][255],dp[255],next[105];
int alt,dt,all,n;
int max(int a,int b)
{
    return a>b?a:b;
}
void insert(int u,int v,int t)
{
    e[all].u=u;
    e[all].v=v;
    e[all].t=t;
    e[all].next=next[u];
    next[u]=all++;
    e[all].u=v;
    e[all].v=u;
    e[all].t=t;
    e[all].next=next[v];
    next[v]=all++;
}
int dfs(int u,int pre)
{
    if(u==n)/*改成之前的if(v==n)
                      {
                         path[u]=path[v]=1;return e[x].t就错了。。。
                                }*/
    {
        path[u]=1;
        return 0;
    }
    int v,x,ret;
    for(x=next[u];x!=-1;x=e[x].next)
    {
        v=e[x].v;
        if(v==pre)continue;
        ret=dfs(v,u);
        if(ret>=0)
        {
            path[u]=1;
            return ret+e[x].t;
        }
    }
    return -1;
}
void dfs2(int u,int pre)
{
    int v,x,j,k;
    get[u][0]=val[u];
    for(x=next[u];x!=-1;x=e[x].next)
    {
        v=e[x].v;
        if(v==pre)continue;
        dfs2(v,u);
        if(path[v])continue;
        for(j=254;j>=0;j--)
          for(k=0;k<=254;k++)//从小到大
          if(k+e[x].t<=j&&get[u][j-e[x].t-k]!=-1)
              get[u][j]=max(get[u][j],get[u][j-k-e[x].t]+get[v][k]);
    }
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&dt)!=EOF)
    {
        memset(next,-1,sizeof(next));
        memset(dp,0,sizeof(dp));
        memset(get,-1,sizeof(get));
        memset(path,0,sizeof(path));
        all=0;
        for(i=1;i<n;i++)
        {
            int u,v,t;
            scanf("%d%d%d",&u,&v,&t);
            insert(u,v,t);
        }
        for(i=1;i<=n;i++)
        scanf("%d",&val[i]);
        alt=dfs(1,0);
        if(alt>dt)
        {
            printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
            continue;
        }
        dfs2(1,0);
         for(i=1;i<=n;i++)
          if(path[i])
           for(j=254;j>=0;j--)
             for(k=0;k<=254;k++)
             if(j-k>=0)
             dp[j]=max(dp[j],dp[j-k]+get[i][k]);
          printf("%d\n",dp[(dt-alt)>>1]);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值