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 }