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): 1845 Accepted Submission(s): 562


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


Source
2012 ACM/ICPC Asia Regional Changchun Online


Recommend
liuyiding

 

参考: http://blog.csdn.net/sprintfwater/article/details/7961372

 

//    树形DP . 感觉做了几题还不是很熟,特别是对状态转移概念还不够清晰,这题的小变形在于先把最短路上的点连起来当成是一个整体,在和其他边做一次树形DP

//    这里的价值要在dfs里的前面加上,因为花费和价值是分开且计算是不一样的,来回一次别的边要 2*该边花费 。 

 1 //125MS    504K    2099 B    C++
 2 /*
 3     树形DP:
 4         
 5     dp[i][j]代表花费时间j从i到n所获得的最大价值
 6     思路:
 7         先将1到n的路径连成一段,再将总时间减去1到n的最短
 8     路劲,在那一段上与其他边进行背包处理
 9     
10     关键状态方程:
11 
12     t0 = V[u][i].t*2;
13 
14     for(j = T; j >= t0; j--)
15         
16         for(k = t0; k <= j  ; k++)
17         
18             dp[u][j]=max(dp[u][j],dp[u][j-k] + dp[V[u][i].v][k-t0]);
19  
20 */
21 #include<iostream>
22 #include<vector>
23 using namespace std;
24 struct node{
25     int v,t;
26     node(int a,int b){
27         v=a;t=b;
28     }
29 };
30 int w[105];  //记录价值 
31 int dp[105][505]; 
32 vector<node>V[105];
33 int n,m,sum;
34 int find(int u,int fa) //递归求最短路(注意无环) 
35 {
36     if(u==n) return 1;
37     int n0=V[u].size();
38     for(int i=0;i<n0;i++){
39         int v0=V[u][i].v;
40         if(v0==fa) continue;
41         if(find(v0,u)){
42             sum+=V[u][i].t;
43             V[u][i].t=0;
44             return 1;
45         }
46     }
47     return 0;
48 }
49 void dfs(int u,int fa)
50 {
51     for(int i=0;i<=m;i++)//加上u点的价值 
52         dp[u][i]+=w[u];
53     int n0=V[u].size();
54     for(int i=0;i<n0;i++){
55         int v0=V[u][i].v;
56         int t0=2*V[u][i].t;
57         if(v0==fa) continue;
58         dfs(v0,u);
59         for(int j=m;j>=t0;j--){
60             for(int k=t0;k<=j;k++)
61                 dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v0][k-t0]);
62             //printf("dp[%d][%d]=%d\n",u,j,dp[u][j]);
63         }
64     } 
65 }
66 int main(void)
67 {
68     int a,b,t;
69     while(scanf("%d%d",&n,&m)!=EOF)
70     {
71         memset(w,0,sizeof(w));
72         memset(dp,0,sizeof(dp));
73         for(int i=0;i<=n;i++) V[i].clear();
74         sum=0;
75         for(int i=1;i<n;i++){
76             scanf("%d%d%d",&a,&b,&t);
77             V[a].push_back(node(b,t));
78             V[b].push_back(node(a,t));
79         }
80         for(int i=1;i<=n;i++) scanf("%d",&w[i]);
81         find(1,0);
82         if(sum>m){
83             puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
84             continue;
85         }
86         m-=sum;
87         dfs(1,0);
88         printf("%d\n",dp[1][m]);
89     }
90     return 0;
91 }

 

转载于:https://www.cnblogs.com/GO-NO-1/articles/3356763.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值