zoukankan      html  css  js  c++  java
  • HDU 4276:The Ghost Blows Light 树形DP(2012 ACM/ICPC Asia Regional Changchun Online )

    The Ghost Blows Light

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4276

    题意:

    胡八一(男主角)被关在一个树形的墓地的根节点1上,现在他有T分钟逃离墓地,墓地的出口在N点,每条边都有权值wi(即经过这条边需要花费wi分钟),每个节点上都有宝藏,求在成功逃离墓地的前提下能获得的最多的宝物。

    题解:

    因为终点只有一个点N,所以可以视为其他所有的节点跑完后都需要折返回N点。将点1到点N的路径上的权值以及宝藏全都清零,更新答案以及T值(因为这条路径是必跑的)。

    那么问题就简化为了在上一步的基础上,所有的节点在跑完后都需要折返回1,再从1跑到点N(花费为0),跑一遍树形DP就可以得到答案了。

          

    代码

     

    #include<stdio.h>
    #include<string.h>
    const int N=101;
    const int M=501;
    const int L=N*2;
    struct edge
    {
      int v,w,next;
    }E[L*2];
    int head[N],cnt,res,m,value[N],dp[N][M];
    int mmax(int x,int y)
    {
      return x>y?x:y;
    }
    bool mark[N];
    void clean(int n)
    {
      cnt=res=0;
      for(int i=1;i<=n;++i)
        head[i]=-1;
    }
    void add(int u,int v,int w)
    {
      E[cnt].v=v;
      E[cnt].w=w;
      E[cnt].next=head[u];
      head[u]=cnt++;
    }
    bool Dfs_Findpath(int id,int n,int time)
    {
      if(time<0)return false;
      mark[id]=true;
      for(int i=head[id];i!=-1;i=E[i].next)
      {
        int v=E[i].v;
        if(mark[v])continue;
        if(v==n||Dfs_Findpath(v,n,time-E[i].w))
        {
          if(v==n)
          {
            m=time-E[i].w;
            if(m<0)return false;
          }
          E[i].w=0;
          res+=value[v];
          value[v]=0;
          return true;
        }
      }
      return false;
    }
    void Dfs_TreeDp(int id)
    {
      mark[id]=true;
      for(int i=head[id];i!=-1;i=E[i].next)
      {
        int v=E[i].v;
        int w=E[i].w;
        if(mark[v])continue;
        Dfs_TreeDp(v);
        for(int j=m;j>=0;--j)
        {
          for(int k=0;k<=j&&j-k-w*2>=0;++k)
            dp[id][j]=mmax(dp[id][j],dp[id][j-k-w*2]+dp[v][k]+value[v]);
        }
      }
    }
    void solve()
    {
      int n,a,b,c;
      while(~scanf("%d%d",&n,&m))
      {
        clean(n);
        for(int i=1;i<n;++i)
        {
          scanf("%d%d%d",&a,&b,&c);
          add(a,b,c);
          add(b,a,c);
        }
        for(int i=1;i<=n;++i)
          scanf("%d",&value[i]);
        if(n==1)
        {
          printf("%d ",value[1]);
          continue;
        }
        memset(mark,false,sizeof(mark));
        if(!Dfs_Findpath(1,n,m))printf("Human beings die in pursuit of wealth, and birds die in pursuit of food! ");
        else
        {
          memset(mark,false,sizeof(mark));
          memset(dp,0,sizeof(dp));
          Dfs_TreeDp(1);
          printf("%d ",res+dp[1][m]+value[1]);
        }
      }
    }
    int main()
    {
      solve();
      return 0;
    }

      

  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5705732.html
Copyright © 2011-2022 走看看