BNUOJ 26283 The Ghost Blows Light

The Ghost Blows Light

Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 4276
64-bit integer IO format: %I64d      Java class name: Main
 
 
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

Source

 
 
解题:树形dp...此题要求从1 入从N出,由于是树,故只有一条路径从1通往N.只需要求出这题路径上的时间和,并且将时间置为0.然后在总时间中减去这部分时间再进行dp.为什么要求和呢?首要原因是判断能否活命!人为财死,鸟为食亡。
有人去求最短路!我只想说,只有一条路径,求最短路有意义吗?
 
如果这题路径上的时间和比给出的时间还大,必死无疑!为什么要置0呢?因为这部分的时间是必须要花掉的!!!!!不然还活不活啊?置零后减去就好了!由于不需花费时间,这些边,根据dp的设计,这些路径上的财富一定会被拿掉的!因为一直取max啊!不要任何消耗就能更大!有点贪心啊
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define INF 0x3f3f3f3f
15 using namespace std;
16 const int maxn = 110;
17 struct arc {
18     int to,w;
19 };
20 int dp[maxn][510],val[maxn],n,t,sum;
21 vector<arc>g[maxn];
22 bool dfs1(int u, int fa){
23     if(u == n) return true;
24     for(int i = 0; i < g[u].size(); i++){
25         if(g[u][i].to == fa) continue;
26         if(dfs1(g[u][i].to,u)){
27             sum += g[u][i].w;
28             g[u][i].w = 0;
29             return true;
30         }
31     }
32     return false;
33 }
34 void dfs(int u,int fa) {
35     for(int i = 0; i <= t; i++) dp[u][i] = val[u];
36     for(int v = 0; v < g[u].size(); v++) {
37         if(g[u][v].to == fa) continue;
38         dfs(g[u][v].to,u);
39         int cost = 2*g[u][v].w;
40         for(int j = t; j >= cost; j--){
41             for(int k = 0; k <= j - cost; k++)
42                 dp[u][j] = max(dp[u][j],dp[u][j-k-cost]+dp[g[u][v].to][k]);
43         }
44     }
45 }
46 int main() {
47     int u,v,w,i;
48     while(~scanf("%d %d",&n,&t)) {
49         for(i = 0; i <= n; i++)
50             g[i].clear();
51         for(i = 1; i < n; i++) {
52             scanf("%d %d %d",&u,&v,&w);
53             g[u].push_back((arc) {v,w});
54             g[v].push_back((arc) {u,w});
55         }
56         for(i = 1; i <= n; i++)
57             scanf("%d",val+i);
58         memset(dp,0,sizeof(dp));
59         sum = 0;
60         dfs1(1,-1);
61         if(sum > t){
62             puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
63             continue;
64         }
65         t -= sum;
66         dfs(1,-1);
67         cout<<dp[1][t]<<endl;
68     }
69     return 0;
70 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/3904677.html