• 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;
    }

      

  • 相关阅读:
    VWG中设置URL编码的方法
    wordwrap breakword
    iis6下配置支持.net4.0&发布网站[转]
    MySQL修复打不开的视图定义
    DHTML CSS+JavaScript设计网页链接提示ToolTips
    C# 计算文件的MD5值
    .Net+IIS环境经常出现的问题及排障[转]
    我的WCF之旅(1):创建一个简单的WCF程序[转]
    C#嵌套类的使用方法及特性[转]
    设置<table>的固定长度
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5705732.html
Copyright © 2020-2023  润新知