题目大意:给定一棵有根树,1 号节点为根节点,点有点权,边有边权,初始给定一个价值,每经过一条边都会减少该价值,每经过一个点都会增加相应的答案贡献值,求如何在给定价值的情况下最大化答案贡献,并要求最后在 N 号节点停留,若无法停留,则输出相应字符串。

题解:

首先,不考虑要求在 N 号节点停留的限制,发现就是一个裸的树上背包问题。但是现在多了一个限制条件,我们假设一定可以从根节点走到 N 号节点。

引理:最有情况下,从根节点到 N 号节点的树链中的每一条边经过且仅经过一次。

证明:若先经过树链上的边 e ,再通过 e 返回,再经过其他非树链边之后,再次返回 e,得到的一条路径 P。构造一条路径 P‘,使得在未经过 e 时,先经过 P’ 中的对应非树边,再经过 e ,得到路径 P。发现 P 总是比 P‘ 小 2e 的代价,证毕。

根据引理,又根据从 1 到 N 的路径必须经过的性质,采用将这条树链压缩成一个点,即:将这条路径上的点压缩成一个点,再在新的树上进行树形dp操作,得到的最优解即是全局最优解。对于压缩路径的等价操作是:记录这条必经树链的每条边,将边权全部置为 0 即可。

代码如下

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=105;
  4. const int maxt=505;
  5. int n,t,a[maxn];
  6. struct node{int nxt,to,w;}e[maxn<<1];
  7. int tot=1,head[maxn];
  8. inline void add_edge(int from,int to,int w){
  9. e[++tot]=node{head[from],to,w},head[from]=tot;
  10. }
  11. int d[maxn],pre[maxn],f[maxn][maxt];
  12. void dfs(int u,int fa){
  13. for(int i=head[u];i;i=e[i].nxt){
  14. int v=e[i].to,w=e[i].w*2;
  15. if(v==fa)continue;
  16. dfs(v,u);
  17. for(int j=t;j>=0;j--)
  18. for(int k=0;k<=j-w;k++)
  19. f[u][j]=max(f[u][j],f[u][j-k-w]+f[v][k]);
  20. }
  21. for(int j=0;j<=t;j++)f[u][j]+=a[u];
  22. }
  23. void getdis(int u,int fa){
  24. for(int i=head[u];i;i=e[i].nxt){
  25. int v=e[i].to,w=e[i].w;
  26. if(v==fa)continue;
  27. pre[v]=i,d[v]=d[u]+w;
  28. getdis(v,u);
  29. }
  30. }
  31. void clear(){
  32. int now=n;
  33. while(now!=1){
  34. int id=pre[now];
  35. e[id].w=e[id^1].w=0;
  36. now=e[id^1].to;
  37. }
  38. }
  39. void read_and_parse(){
  40. for(int i=1;i<n;i++){
  41. int x,y,z;
  42. scanf("%d%d%d",&x,&y,&z);
  43. add_edge(x,y,z),add_edge(y,x,z);
  44. }
  45. for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  46. }
  47. void solve(){
  48. getdis(1,0);
  49. if(d[n]>t)return (void)puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
  50. clear();
  51. t-=d[n];
  52. dfs(1,0);
  53. printf("%d\n",f[1][t]);
  54. }
  55. void init(){
  56. memset(head,0,sizeof(head)),tot=1;
  57. memset(pre,0,sizeof(pre));
  58. memset(d,0,sizeof(d));
  59. memset(f,0,sizeof(f));
  60. }
  61. int main(){
  62. while(scanf("%d%d",&n,&t)!=EOF){
  63. init();
  64. read_and_parse();
  65. solve();
  66. }
  67. return 0;
  68. }

【HDU4276】The Ghost Blows Light的更多相关文章

  1. 【HDU 4276】The Ghost Blows Light(树形DP,依赖背包)

    The Ghost Blows Light Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The t ...

  2. HDU 4276 The Ghost Blows Light

    K - The Ghost Blows Light Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  3. BNUOJ 26283 The Ghost Blows Light

    The Ghost Blows Light Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...

  4. HDU4276 The Ghost Blows Light(树形DP+背包)

    题目大概说一棵n个结点树,每个结点都有宝藏,走过每条边要花一定的时间,现在要在t时间内从结点1出发走到结点n,问能获得最多的宝藏是多少. 放了几天的题,今天拿出来集中精力去想,还是想出来了. 首先,树 ...

  5. 树形DP(01组合背包The Ghost Blows Light HDU4276)

    题意:有n个房间,之间用n-1条道路连接,每个房间都有一个定时炸弹,在T时间后会一起爆炸,第i个房间有pi价值的珠宝,经过每条道路都需要花费一定的时间,一个人从1房间开始 ,从n房间出去,保证再不炸死 ...

  6. HDU-4276 The Ghost Blows Light (树形DP+背包)

    题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口.每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少? 题目分析:在树上,从 ...

  7. HDU4276 The Ghost Blows Light SPFA&&树dp

    题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739 做这道题主要是为了加强自己对SPFA的代码的训练 ...

  8. HDU4276 - The Ghost Blows Light(树形DP)

    题目大意 给定一棵n个结点的树,每个结点上有一定数量的treasure,经过每条边需要花一定的时间,要求你从结点1出发,在不超过时间T的情况下,最多能够获得的treasure是多少,并且要求结束于结点 ...

  9. HDU 4276-The Ghost Blows Light(树状背包)

    题意: n个房间,每个有一定的钱,一个房间到另一个房间花费一定的时间,给你房间连接树,求在t时间内到达房间m能得到的最大钱数(从房间1(根)出发) 分析: 该题关键是最后要到达m,没有这个条件,就是基 ...

随机推荐

  1. Jmeter之乱码 (三)

    使用Jmeter执行JDBC请求,往MySQL数据库中插入数据,如下图: 执行结果如下: 解决方案: 在JDBC Connection Configuration中的Database URL后加上&a ...

  2. JS实战篇

    实现选项卡的选择: 效果图如下: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  3. Kafka sender消息生产者

    1.pom文件引入Kafka依赖(我用的版本是2.2.2.RELEASE) <dependency> <groupId>org.springframework.kafka< ...

  4. Docker】如何修改Docker的默认镜像存储位置

    江湖有多大,坑就有多多……我使用的服务器, 系统盘根目录只有20G, 默认Docker 的镜像文件是安装在/var/lib/docker 目录下的, 这样的话我根本装不了太多的镜像,之前遇到一种情况就 ...

  5. 车牌识别1:License Plate Detection and Recognition in Unconstrained Scenarios阅读笔记

    一.WHAT 论文下载地址:License Plate Detection and Recognition in Unconstrained Scenarios [pdf] github 的项目地址: ...

  6. 笔记纪要:C# WebService URL重写

    背景# 有时候我们会有这样的需求,将 WebService URL 中的 asmx 后缀去掉:或者我们要模拟普通 Web 的 URL,接口名称直接拼接在 URL 中.这些情况我们都要用到URL重写. ...

  7. jenkins自动化部署工具

    jenkins自动化测试 & 持续集成 知识点: 1.下载地址:jenkins.io download:

  8. Android 透明主题

    转至:https://blog.csdn.net/zhangwenchaochao/article/details/78654128 Activity采用透明主题有两种方式: 重要的内容说三遍: 采用 ...

  9. POJ 3585 Accumulation Degree 题解

    题面 一句话题意:找一个点使得,使得从这个点出发作为源点,发出的流量最大,输出这个最大的流量 这道题是换根法+二次扫描的模板: 首先若确定1为原点,那么可以写出dp方程:当v的度是1时, g[u]+= ...

  10. 直线的Bresenham算法

    在实验课上用自己的算法画直线被diss效率低 花了半天时间看了下Bresenham算法真