HDU4276 The Ghost Blows Light(树形DP+背包)
题目大概说一棵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+背包)的更多相关文章
- HDU4276 - The Ghost Blows Light(树形DP)
题目大意 给定一棵n个结点的树,每个结点上有一定数量的treasure,经过每条边需要花一定的时间,要求你从结点1出发,在不超过时间T的情况下,最多能够获得的treasure是多少,并且要求结束于结点 ...
- 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 ...
- HDU-4276 The Ghost Blows Light (树形DP+背包)
题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口.每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少? 题目分析:在树上,从 ...
- HDU4276 The Ghost Blows Light SPFA&&树dp
题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739 做这道题主要是为了加强自己对SPFA的代码的训练 ...
- 【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 ...
- HDU 4276 The Ghost Blows Light
K - The Ghost Blows Light Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- BNUOJ 26283 The Ghost Blows Light
The Ghost Blows Light Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- HDU 4276 The Ghost Blows Light(树形)
题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T.问从1到达n在给定时间T内取得的最大价值? 思路:先从1走到n,如果总的时间不够走完,直接退出, ...
随机推荐
- URL编码表,URL编码大全
url编码是一种浏览器用来打包表单输入的格式. 定义 url编码是一种浏览器用来打包表单输入的格式.浏览器从表单中获取所有的name和其中的值 ,将它们以name/value参数编码(移去那些不能传送 ...
- centos安装配置nginx
1.安装gcc yum install gcc 2.安装PCRE,zlib,OpenSSL(其中devel,是develop开发包的意思) yum install -y pcre pcre-devel ...
- ios 应用程序图标、启动画面、itune图标设置
http://blog.sina.com.cn/s/blog_4cd8dd1301014hfz.html 先说说应用程序图标,一般有下面几种: Icon.png(57x57) - Homescreen ...
- [codeforces 516]A. Drazil and Factorial
[codeforces 516]A. Drazil and Factorial 试题描述 Drazil is playing a math game with Varda. Let's define ...
- [BZOJ3786]星系探索
[BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...
- 【Django】如何自定义manage.py命令? 达到启动后台进程的目的?
代码: #-*- coding:utf- -*- """ The handle active user mail send """ from ...
- 47. 数组中出现次数超过一半的数字[Number appears more than half times]
[题目]:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字. 例如长度为9的数组{1,2,3,2,2,2,5,4,2}中次数超过了数组长度的一半的数字为2,而长度为8的数组{1,2,3,2 ...
- java 和 objective-c 动态获得类型信息
详细信息,请参看android官方文档中的class类的介绍 ,和苹果的官方文档Objective-C Runtime Reference java中常常听到反射reflection,在java的cl ...
- css form 表单组对齐
2014年7月1日 15:31:17 第一次写css,见谅 css: .form-box .form-group .form-label {text-align: right; width: 200p ...
- Java for LeetCode 042 Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...