zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    (转)SQL Server 2005两种安全验证模式
    C#练习题记录(交换两个数1)
    C# using 用法
    服务器的理解(菜鸟)
    zZ
    ZzZ
    [转]Arcgis制作泰森多边形具体步骤
    [转]免费网站推广
    [转]如何让Firefox优化得比Chrome更快
    [转]3天搞定网站重新被百度收录的方法
  • 原文地址:https://www.cnblogs.com/Xiper/p/4902844.html
Copyright © 2011-2022 走看看