HDU 4276 The Ghost Blows Light (树形DP,变形)

题意:给定一棵n个节点的树,起点是1,终点是n,每经过一条边需要消耗Ti天,每个点上有一定量的珠宝,要求必须在t天内到达终点才可以将珠宝带出去,问至多能带多少珠宝?

思路:

  注意Ti可以为0,而且有可能t太小以至于不能到达n,则输出不可达。这样想会简单点,将"1->n"路径上的每条边断开,变成一片森林,而且路径上的这些点是根。我们需要计算每棵树在j天内最多能获得多少珠宝,这只需要一次DFS就可以完成了。然后除了森林中的根(即1->n路径上的点),其他都可以不用考虑了,按照"1->n"路径的方向,逐个点进行转移,更新dp值,到最后dp[n][t]就是答案了。最后这步是“至少带走1件物品”分组背包模型,只需要先将1件物品丢进背包,有好的就更新,没有的话也保证了至少带1件物品。

  

  1 //#include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <map>
  7 #include <deque>
  8 #include <algorithm>
  9 #include <vector>
 10 #include <iostream>
 11 #define pii pair<int,int>
 12 #define INF 0x3f3f3f3f
 13 #define LL  long long
 14 using namespace std;
 15 const double PI  = acos(-1.0);
 16 const int N=110;
 17 int n, edge_cnt, head[N], w[N], dp[N][550], cap[550];
 18 struct node
 19 {
 20     int from, to, cost, next, tag;
 21     node(){};
 22     node(int from,int to,int cost,int next):from(from),to(to),cost(cost),next(next){tag=0;};
 23 }edge[N*2];
 24
 25 deque<pii> que;
 26 void add_node(int from,int to,int cost)
 27 {
 28     edge[edge_cnt]=node(from,to,cost,head[from]);
 29     head[from]=edge_cnt++;
 30 }
 31
 32 bool dfs(int t,int far,int m)
 33 {
 34     int flag=false;
 35     if(m<0) return false;   //不可到达
 36
 37     for(int i=0; i<=m; i++) dp[t][i]=w[t];      //到达本点至少获得w[t]
 38     node e;
 39     for(int i=head[t]; i!=-1; i=e.next)
 40     {
 41         e=edge[i];
 42         if(e.to==far)   continue;
 43         if(dfs(e.to, t, m-e.cost)==true)
 44         {
 45             que.push_back(make_pair(e.to, e.cost));
 46             flag=true;
 47             edge[i].tag=1;
 48         }
 49         else
 50         {
 51             for(int j=m; j>=0; j--)
 52                 for(int k=2*e.cost; k<=j; k++) //枚举给此孩子k-2*cost天的时间
 53                     dp[t][j]=max(dp[t][j], dp[t][j-k]+dp[e.to][k-2*e.cost] );
 54         }
 55     }
 56     if(t==n)    return true;    //终点站
 57     else        return flag;
 58 }
 59
 60 int main()
 61 {
 62     freopen("input.txt", "r", stdin);
 63     int m, a, b, c;
 64     while(~scanf("%d%d",&n,&m))
 65     {
 66         que.clear();
 67         edge_cnt=0;
 68         memset(head,-1,sizeof(head));
 69         memset(dp,0,sizeof(dp));
 70         memset(cap,0,sizeof(cap));
 71
 72         for(int i=1; i<n; i++)
 73         {
 74             scanf("%d%d%d",&a,&b,&c);
 75             add_node(a,b,c);
 76             add_node(b,a,c);
 77         }
 78         for(int i=1; i<=n; i++) scanf("%d",&w[i]);
 79         if(dfs(1,-1,m)==true)
 80         {
 81             reverse(que.begin(),que.end()); //变成1条链,逐个节点进行“至少带1件物品的分组背包”
 82             que.push_front(make_pair(1,0));
 83             int t, c, st=0;
 84             while(!que.empty())
 85             {
 86                 t=que.front().first;    //当前点已经在t
 87                 c=que.front().second;   //转移到t的花费
 88                 que.pop_front();
 89                 st+=c;
 90
 91                 for(int j=m; j>=st; j--)
 92                 {
 93                     cap[j]=cap[j-c]+dp[t][0];  //从上个点转移到t至少需先消耗c
 94                     for(int k=1; k+st<=j; k++)
 95                         cap[j]=max(cap[j], cap[j-k-c]+dp[t][k]);
 96                 }
 97             }
 98             printf("%d\n", cap[m]);
 99         }
100         else puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");//不可达
101     }
102     return 0;
103 }

AC代码

时间: 2024-10-21 16:30:42

HDU 4276 The Ghost Blows Light (树形DP,变形)的相关文章

HDU4276 The Ghost Blows Light 树形DP

做这个题的时候想到了,先来一遍最短路,判断是否可以到达,若可以减去最短路的花费,再在剩下的花费里进行DP求最优解,想到了但是没做到,很多细节没有处理好,结果崩盘了,唉,看题解很多人都是两边dfs,不过这位大牛也是先spfa了一遍,  给我这个弱菜看看 刚好,这篇好好记录下来, 最后参考了大牛的:http://blog.csdn.net/acm_cxlove/article/details/7964739,可以说是一模一样了 #include<iostream> #include<cstd

hdu 4276 The Ghost Blows Light(DP-树形DP)

The Ghost Blows Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2240    Accepted Submission(s): 688 Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consi

HDU 4276 - The Ghost Blows Light

The Ghost Blows Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3345    Accepted Submission(s): 1040 Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consi

HDU 4276 The Ghost Blows Light(树形)

题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T.问从1到达n在给定时间T内取得的最大价值? 思路:先从1走到n,如果总的时间不够走完,直接退出,否则把时间扣掉,这些边权设置为0,然后做一遍树形DP 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream>

HDOJ 题目4276 The Ghost Blows Light(SPFA+树形DP)

The Ghost Blows Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2549    Accepted Submission(s): 795 Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consi

hdu 1561The more, The Better(树形dp&amp;01背包)

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4949    Accepted Submission(s): 2918 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

HDU 4008 Parent and son LCA+树形dp

题意: 给定case数 给定n个点的树,m个询问 下面n-1行给出树边 m个询问 x y 问:以x为根,y子树下 y的最小点标的儿子节点 和子孙节点 思路: 用son[u][0] 表示u的最小儿子 son[u][2] 表示u的次小儿子 son[u][1] 表示u的最小子孙 若lca(x,y)  !=y  则就是上述的答案 若lca(x,y) == y 1.y != 1 那么最小儿子就是除了x外的节点,且此时father[y] 也是y的儿子节点, 而最小的子孙节点就是1 2.y==1 那么特殊处理

HDU 4274 Spy&#39;s Work (树形DP,模拟)

题意: 给定一棵树,每个节点代表一个员工,节点编号小的级别就小,那么点1就是boss了.接下来给出对m个点的限制,有3种符号分别是op=“大于/小于/等于”,表示以第i个点为根的子树所有人的工资之和 大于/小于/等于 x,要求判断m个限制是否冲突了.注意每个员工的工资下限是1,而无上限.ps:可能出现对同个点多个限制,注意取交集. 思路: 很水的题嘛,想复杂了.注意限制是针对整棵子树的!所以我们只需要算出这棵子树的范围,再判断是否和所给的限制有冲突,如果没有冲突的话还得取“所给限制”与“计算出的

hdu 1011 Starship Troopers (依赖背包 树形dp)

题目: 链接:点击打开链接 题意: n个房间组成一棵树,你有m个战队,从1号房间开始依次clear每个房间,在每个房间需要花费的战队个数是bugs/20,得到的价值是the possibility of capturing a brain,求最大的价值. 算法: 树形dp,有依赖的背包问题.(依次clear每个房间) 思路: 状态转移dp[i][j]表示根结点为i时(房间i)花费j个战队能够得到的最大价值(捕捉到一个brain最大的可能值).递归求出每个根结点处的最大值,最后dp[1][m]就是