The Ghost Blows Light
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3617 Accepted Submission(s): 1159
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)
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个点,n-1条边,时间T。每个点都有一定的价值,而从一个点到另一个边都需要消耗一定的时间,要从节点1在时间T内到达节点n。求能获得的最大价值。
刚开始做这个题的时候没有什么思路,最后还是看了题解的思路。。
先求出从1到n的最短路径,也就是花费时间最短的走法。最短路径只会走一遍,而求出最短路径所需要花费的时间后,剩下的时间t=T-最短路径时间,然后就转化成时间t所能获得的最大价值,所要计算的就是最短路径上的点所能获得的最大价值,也就是从最短路径上的点走出去再回到该点,因为已经减去了最短路径时间,所以我们不用考虑到达点n的问题。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
struct f
{
int fa,val,to;
}tree[205];
int head[105],p;
int n,t,s,dp[105][550],val[105];
void csh()
{
memset(head,-1,sizeof(head));
p=0;
s=0;
}
void build(int son,int fa,int val)
{
tree[p].fa=fa;
tree[p].val=val;
tree[p].to=head[son];
head[son]=p++;
}
int findd(int now,int before)
{
if(now==n)
return 1;
for(int i=head[now];i!=-1;i=tree[i].to)
{
int next=tree[i].fa;
if(next==before)
continue;
if(findd(next,now))
{
s+=tree[i].val;
tree[i].val=0;
return 1;
}
}
return 0;
}
void dfs(int now,int before)
{
for(int i=0;i<=t;i++)
dp[now][i]=val[now];
for(int i=head[now];i!=-1;i=tree[i].to)
{
int next=tree[i].fa;
int val2=tree[i].val;
if(next==before)
continue;
dfs(next,now);
for(int j=t;j>=2*val2;j--)
for(int k=0;k+2*val2<=j;k++)
dp[now][j]=max(dp[now][j],dp[now][j-2*val2-k]+dp[next][k]);
}
}
int main()
{
int a,b,c;
while(~scanf("%d%d",&n,&t))
{
csh();
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
build(a,b,c);
build(b,a,c);
}
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
findd(1,-1);
t-=s;
if(t>=0)
{
memset(dp,0,sizeof(dp));
dfs(1,-1);
cout<<dp[1][t]<<endl;
}
else
cout<<"Human beings die in pursuit of wealth, and birds die in pursuit of food!"<<endl; //当时复制这句话把最后的感叹号漏了,wa两次。。
}
return 0;
}