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

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

题目分析:在树上,从1到n的路径唯一。从1到n的唯一路径叫做主线路,要想走到出口,一定会经过主线路,也就是必须经过主线路上节点。在脱离主线路之前必须要预留出返回的时间。

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;

const int N=105;
const int INF=1000000000;

int n,m;
int d[N];
int dp[N][N*5];
int g[N][N];
int w[N],pre[N];
vector<int>e[N];

void init()
{
	int a,b,c;
	for(int i=1;i<=n;++i)
		e[i].clear();
	for(int i=1;i<n;++i){
		scanf("%d%d%d",&a,&b,&c);
		g[a][b]=g[b][a]=c;
		e[a].push_back(b);
		e[b].push_back(a);
	}
	for(int i=1;i<=n;++i)
		scanf("%d",w+i);
}

void spfa()
{
	fill(pre,pre+n+1,-1);
	fill(d+1,d+n+1,INF);
	queue<int>q;
	q.push(1);
	d[1]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(int i=0;i<e[u].size();++i){
			int v=e[u][i];
			if(d[v]>d[u]+g[u][v]){
				d[v]=d[u]+g[u][v];
				pre[v]=u;
				q.push(v);
			}
		}
	}
}

void dfs(int u,int fa)
{
	fill(dp[u],dp[u]+m+1,w[u]);
	for(int i=0;i<e[u].size();++i){
		int v=e[u][i];
		if(v==fa) continue;
		dfs(v,u);

		int t=2*g[u][v];

		for(int j=m;j>=t;--j)
			for(int k=0;k+t<=j;++k)
				dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k-t]);
	}
}

void solve()
{
	spfa();
	if(d[n]>m){
		printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
	}else{
		int u=n;
		while(pre[u]!=-1){
			g[pre[u]][u]=g[u][pre[u]]=0;
			u=pre[u];
		}
		m-=d[n];
		dfs(1,-1);
		printf("%d\n",dp[1][m]);
	}
}

int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		init();
		solve();
	}
	return 0;
}

  

时间: 2024-10-12 13:23:14

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>

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

题意:给定一棵n个节点的树,起点是1,终点是n,每经过一条边需要消耗Ti天,每个点上有一定量的珠宝,要求必须在t天内到达终点才可以将珠宝带出去,问至多能带多少珠宝? 思路: 注意Ti可以为0,而且有可能t太小以至于不能到达n,则输出不可达.这样想会简单点,将"1->n"路径上的每条边断开,变成一片森林,而且路径上的这些点是根.我们需要计算每棵树在j天内最多能获得多少珠宝,这只需要一次DFS就可以完成了.然后除了森林中的根(即1->n路径上的点),其他都可以不用考虑了,按照&

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 1561 The more, The Better(树形dp+背包)

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6000    Accepted Submission(s): 3548 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻