HDU 4276 The Ghost Blows Light

K - The Ghost Blows Light
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Appoint description: 

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
 
解题报告:
 因为是一棵树,所以起点到终点的路径已经确定了,所以我们可以先暴力出所有路径上的点。
这样路径就是一条链了,之后我们在这条链上每个点进行一次树形背包,然后点之间的转移依旧用背包,就可以得出最终答案了,可以预先处理处1->n的距离,判断无解情况.
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int maxn = 1e2 + 15;
struct Edge {int v,nxt,w;};
Edge e[maxn*5];
int n , T , head[maxn] , tot , val[maxn] , dp[maxn][maxn*5] , ban[maxn] , ans[2][maxn*5] , mat[maxn][maxn];
vector< int >path;

void addedge(int u ,int v,int w) {e[tot].v=v,e[tot].nxt=head[u],e[tot].w=w,head[u]=tot++;}

bool dfs_path(int u,int fa)
{
	if(u==n) 
	{
		path.push_back(u);
		return true;
	}
	for(int i = head[u] ; ~i ; i = e[i].nxt)
	{
		int v = e[i].v;
		if(v==fa) continue;
		if(dfs_path(v,u))
		{
			path.push_back(u);
			return true;
		}
	}
	return false;
}

inline void updata(int & x ,int v)
{
	x = max( x , v);
}

void dfs(int u ,int fa)
{
	for(int i = 0 ; i <= T ; ++ i) dp[u][i] = val[u];
	for(int i = head[u] ; ~i ; i = e[i].nxt)
	{
		int v = e[i].v;
		if(v == fa || ban[v]) continue;
		dfs( v , u );
		for(int j = T ; j >= 0 ; -- j)
		{
			int w = e[i].w;
		    for(int k = T - j - w * 2 ; k >= 0 ; -- k) updata( dp[u][j + k + w * 2] , dp[u][j] + dp[v][k]);
		}
	} 
}

int main(int argc,char *argv[])
{
	while(~scanf("%d%d",&n,&T))
	{
		memset(head,-1,sizeof(head));tot=0;path.clear();memset(ban , 0 , sizeof(ban));memset( ans , 0 , sizeof(ans) ); int costall=0;
		int cur = 0;
		for(int i = 1 ; i < n ; ++ i)
		{
			int u , v , w;scanf("%d%d%d",&u,&v,&w);
			addedge( u , v , w); addedge( v , u , w);
			mat[u][v] = mat[v][u] = w;
		}
		for(int i = 1 ; i <= n ; ++ i) scanf("%d",val+i);
		dfs_path(1,0) ; reverse(path.begin() , path.end());
	    for(int i = 0 ; i < path.size() - 1 ; ++ i) costall += mat[path[i]][path[i+1]];
	    if(costall > T)
	    {
	    	printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!
");
	    	continue;
	    }
	    costall = 0;
	    for(int i = 0 ; i < path.size() - 1 ; ++ i)
	    {
	    	int cost = mat[path[i]][path[i+1]];
	    	ban[path[i]]=1;
	    	ban[path[i+1]] = 1;
	    	int pre = cur ; cur ^= 1;memset(ans[cur] , 0 , sizeof(ans[cur]));
	    	int u = path[i];
	    	dfs( u , -1);
	    	for(int j = T ; j >= costall ; -- j)
	    		for(int k = T - j - cost; k >=0 ; -- k)
	    			updata( ans[cur][j + k + cost] , ans[pre][j] + dp[u][k]);
	    	costall += cost;
	    }
	    int res = 0;
	    dfs( n , -1);
	    for(int i = T ; i >= costall ; -- i)
	    	for(int j = T - i ; j >= 0 ; -- j)
	         res = max( res , ans[cur][i] + dp[n][j]);
	    printf("%d
",res);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/Xiper/p/4902844.html