题目大概说一棵n个结点树,每个结点都有宝藏,走过每条边要花一定的时间,现在要在t时间内从结点1出发走到结点n,问能获得最多的宝藏是多少。

放了几天的题,今天拿出来集中精力去想,还是想出来了。

首先,树上任意两点间最短的那条路径是唯一的,且不管怎么走一定都会走过那条路径上的所有点,也就是说整个行程可以看成两部分组成:一部分就是1到n的最短路径,另一部分就是从这个路径上的某点出发绕回该点的路径。

这样问题就清晰了,现在关键在求第二部分:

  • 先用树上背包求出:dp[u][t],表示从在以u点为根的子树中从u点出发且不经过n结点及其祖先结点最后回到u点总共用时t能获得最多的宝藏
  • 最后从1到n最短的那条路径上的各个点u看作物品,有t种规格的体积,每种体积价值是dp[u][t],背包容量为总时间-走那条最短路所需时间,这样再做一次背包,求出装满某体积(用某时间)能得到的最大价值就OK了。
  • 注意的是那个状态是不经过n结点及其祖先结点,这是为了不重复统计,1到n路径上的点本身就是父子关系。
 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 111
struct Edge{
int v,w,next;
}edge[MAXN<<];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
head[u]=NE++;
}
int n,t,val[MAXN],d[MAXN][],par[MAXN],weight[MAXN];
bool dp(int u){
bool flag=;
d[u][]=val[u];
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==par[u]) continue;
par[v]=u;
weight[v]=edge[i].w;
if(dp(v)){
flag=;
continue;
}
for(int j=t; j>=; --j){
for(int k=; ; ++k){
if(edge[i].w*+k>j) break;
if(d[v][k]==- || d[u][j-edge[i].w*-k]==-) continue;
d[u][j]=max(d[u][j],d[u][j-edge[i].w*-k]+d[v][k]);
}
}
}
if(u==n) return ;
return flag;
}
int rec[MAXN],rn,tot;
void dfs(int u){
if(u!=){
tot+=weight[u];
dfs(par[u]);
}
rec[rn++]=u;
}
int ans[MAXN][];
int main(){
int a,b,c;
while(~scanf("%d%d",&n,&t)){
NE=;
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c);
addEdge(b,a,c);
}
for(int i=; i<=n; ++i) scanf("%d",val+i);
memset(d,-,sizeof(d));
dp();
rn=tot=;
dfs(n);
tot=t-tot;
memset(ans,-,sizeof(ans));
for(int i=; i<=tot; ++i) ans[][i]=d[rec[]][i];
for(int i=; i<rn; ++i){
for(int j=; j<=tot; ++j){
for(int k=; k<=tot; ++k){
if(j+k>tot || ans[i-][j]==- || d[rec[i]][k]==-) continue;
ans[i][j+k]=max(ans[i][j+k],ans[i-][j]+d[rec[i]][k]);
}
}
}
int res=-;
for(int i=; i<=tot; ++i) res=max(res,ans[rn-][i]);
if(res==-) puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
else printf("%d\n",res);
}
return ;
}

HDU4276 The Ghost Blows Light(树形DP+背包)的更多相关文章

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

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

  2. HDOJ 4276 The Ghost Blows Light(树形DP)

    Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consists of N room ...

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

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

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

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

  5. 【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 ...

  6. HDU 4276 The Ghost Blows Light

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

  7. BNUOJ 26283 The Ghost Blows Light

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

  8. URAL_1018 Binary Apple Tree 树形DP+背包

    这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...

  9. HDU 4276 The Ghost Blows Light(树形)

    题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T.问从1到达n在给定时间T内取得的最大价值? 思路:先从1走到n,如果总的时间不够走完,直接退出, ...

随机推荐

  1. java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合

    关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...

  2. [Effective JavaScript 笔记]第50条:迭代方法优于循环

    "懒"程序员才是好程序员.复制和粘贴样板代码,一但代码有错误,或代码功能修改,那么程序在修改的时候,程序员需要找到所有相同功能的代码一处处进行修改.这会使人重复发明轮子,而且在别人 ...

  3. DELPHI设置枚举类型size

    delphi枚举类型长度默认为2个字节(单字),而在C中枚举为4个字节(双字),如果需要跨这两个平台编程,传输结构时会由于数据长度不一造成灾难. 经过查找资料,原来delphi可以通过{$Z+} {$ ...

  4. NYOJ 106背包问题

    http://acm.nyist.net/JudgeOnline/problem.php?pid=106 背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现 ...

  5. 【SpringMVC】SpringMVC系列14之SpringMVC国际化

    14.SpringMVC国际化 14.1.概述 14.2.用户切换选择语言

  6. Combination Sum | & || & ||| & IV

    Combination Sum | Given a set of candidate numbers (C) and a target number (T), find all unique comb ...

  7. eclipse workspace 共享配置文件

    eclipse workspace 共享设置 配置文件记录了原来工程的使用习惯,如字体.编码格式等等,通过拷贝替换达到共享配置的目的. 总结一下,复制工作空间配置步骤如下: 1 使用eclipse新建 ...

  8. elk+redis分布式分析nginx日志

    一.elk套件介绍 ELK 由 ElasticSearch . Logstash 和 Kiabana 三个开源工具组成.官方网站: https://www.elastic.co/products El ...

  9. codeforces A. Vasily the Bear and Triangle 解题报告

    题目链接:http://codeforces.com/problemset/problem/336/A 好简单的一条数学题,是8月9日的.比赛中没有做出来,今天看,从pupil变成Newbie了,那个 ...

  10. mybatisforeach循环,传入多个参数

    上代码: controller: @RequestMapping(value = "/findPage", method = RequestMethod.POST) @Respon ...