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 consists of N
rooms (numbered from 1 to N) which are connected by some roads (pass
each road should cost some time). There is exactly one route between any
two rooms, and each room contains some treasures. Now I am located at
the 1st room and the exit is located at the Nth room.
Suddenly,
alert occurred! The tomb will topple down in T minutes, and I should
reach exit room in T minutes. Human beings die in pursuit of wealth, and
birds die in pursuit of food! Although it is life-threatening time, I
also want to get treasure out as much as possible. Now I wonder the
maximum number of treasures I can take out in T minutes.

Input

  There are multiple test cases.
The first line contains two integer N and T. (1 <= n <= 100, 0 <= T <= 500)
Each
of the next N - 1 lines contains three integers a, b, and t indicating
there is a road between a and b which costs t minutes. (1<=a<=n,
1<=b<=n, a!=b, 0 <= t <= 100)
The last line contains N integers, which Ai indicating the number of treasure in the ith room. (0 <= Ai <= 100)

Output

  For
each test case, output an integer indicating the maximum number of
treasures I can take out in T minutes; if I cannot get out of the tomb,
please output "Human beings die in pursuit of wealth, and birds die in
pursuit of food!".

Sample Input

5 10

1 2 2

2 3 2

2 5 3

3 4 3

1 2 3 4 5

Sample Output

11

题意:

  有一棵树,有n个节点,每个节点有一个权值,每一条边有一个时间,在经过的时间不超过给定时间m的情况下,求从1点到n点的路径的最大权值

思路:

  对于一棵树只有一条 从根节点到某节点的最短路,所以先判断这条最短路是不是符合条件,符合的话,把这条路上的点记为0,然后就是树形DP求解,

因为要走其他点,必须再回来,所以回来时要乘以二所经过的路径

这是个背包问题:

状态转移方程为,dp[i][j]=max(dp[i][j],dp[i][k]+dp[i][j-2*val-k])

AC代码:

 1 # include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int MAX = 120;
 5 struct node
 6 {
 7     int to;
 8     int next;
 9     int t;
10 }tree[MAX];
11 int head[MAX];
12 int tol = 0;
13 int w[MAX];
14 int n, t;
15 int Mint;
16 int dp[MAX][600];
17
18 void add(int a, int b, int val)
19 {
20     tree[tol].to = b;
21     tree[tol].next = head[a];
22     tree[tol].t = val;
23     head[a] = tol++;
24 }
25
26 bool dfs1(int root, int f)
27 {
28     if(root == n)
29         return true;//找到了
30     for(int i = head[root]; i != -1; i = tree[i].next)
31     {
32         int son = tree[i].to;
33         if(son == f)
34             continue;
35         if(dfs1(son, root))
36         {
37             Mint += tree[i].t;
38             tree[i].t = 0;
39             return true;
40         }
41     }
42     return false;
43 }
44
45 void dfs2(int root, int f)
46 {
47     for(int i = 0; i <= t; i++)
48         dp[root][i] = w[root];
49     for(int i = head[root]; i != -1; i = tree[i].next)
50     {
51         int son = tree[i].to;
52         if(son == f)
53             continue;
54         dfs2(son, root);
55         int cost = tree[i].t * 2;
56         for(int j = t; j >= cost; j--)
57         {
58             for(int k = 0; k <= j - cost; k++)
59                 dp[root][j] = max(dp[root][j], dp[root][j - k - cost] + dp[son][k]);
60         }
61     }
62 }
63 int main()
64 {
65     while(scanf("%d%d", &n, &t) != EOF)
66     {
67         memset(head, -1, sizeof(head));
68         memset(dp, 0, sizeof(dp));
69         tol = 0;
70         Mint = 0;
71         int a, b, val;
72         for(int i = 1; i < n; i++)
73         {
74             scanf("%d%d%d", &a, &b, &val);
75             add(a, b, val);
76             add(b, a, val);
77         }
78         for(int i = 1; i <= n; i++)
79         {
80             scanf("%d", &w[i]);
81         }
82         dfs1(1, -1);// 看看直接走去的最短时间是多少,
83         if(Mint > t)
84         {
85             printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
86             continue;
87         }
88         t -= Mint;
89         dfs2(1, -1);
90         printf("%d\n", dp[1][t]);
91     }
92     return 0;
93 }

时间: 2024-08-10 15:05:09

HDU 4276 - The Ghost Blows Light的相关文章

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 (树形DP,变形)

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

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

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(树状背包)

题意: n个房间,每个有一定的钱,一个房间到另一个房间花费一定的时间,给你房间连接树,求在t时间内到达房间m能得到的最大钱数(从房间1(根)出发) 分析: 该题关键是最后要到达m,没有这个条件,就是基础的树形背包,哎,一开始没思路,放了一段时间,看看题解才明白,该题突破口,就是,你先想怎么判断不能到到达m的情况,自然想到最短路,对树先求一次最短路,在最短路上的点只能,过一次,其他得点过两次,把最短路上的点花费置零,剩下的就是基础的树形背包. #include <map> #include &l

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

题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口.每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少? 题目分析:在树上,从1到n的路径唯一.从1到n的唯一路径叫做主线路,要想走到出口,一定会经过主线路,也就是必须经过主线路上节点.在脱离主线路之前必须要预留出返回的时间. 代码如下: # include<iostream> # include<cstdio> # include<vector>

hdu 4276(树形dp)

题意:带权树上有起点终点每个点上有宝藏,一个人只有T分钟要从起点到重点,问你最多能收集多少宝藏. 思路:树形dp,首先判断能不能走到终点,然后把路径上的边权变为0时间减去所有边权.dp[v][j]表示从v出发回到v话费j分钟最多能收集到的宝藏. dp[v][j] = max(dp[v][j], dp[x][k] + dp[v][j-k-2*val]); 被G++卡了好长时间,换成c++就过了. 代码如下: 1 #include <stdio.h> 2 #include <string.h

HDU 4276

题意:你在一座古墓里盗墓,古墓在T分钟时就会倒塌,你就挂了.古墓有n个房间,每个房间都有一定价值的宝藏,n-1条边,每条边有花费的时间,形成一棵树.如果逃不出去就输出Human beings die in pursuit of wealth, and birds die in pursuit of food!  如果能逃出去,那么输出能获得的最大价值是多少. 思路:先dfs算出到n点的最短路,然后判断时间是否大于T.如果大于T就输出Human beings die in pursuit of w