zoukankan      html  css  js  c++  java
  • HDU-4276 The Ghost Blows Light (树形DP+背包)

    题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口。每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少?

    题目分析:在树上,从1到n的路径唯一。从1到n的唯一路径叫做主线路,要想走到出口,一定会经过主线路,也就是必须经过主线路上节点。在脱离主线路之前必须要预留出返回的时间。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=105;
    const int INF=1000000000;
    
    int n,m;
    int d[N];
    int dp[N][N*5];
    int g[N][N];
    int w[N],pre[N];
    vector<int>e[N];
    
    void init()
    {
    	int a,b,c;
    	for(int i=1;i<=n;++i)
    		e[i].clear();
    	for(int i=1;i<n;++i){
    		scanf("%d%d%d",&a,&b,&c);
    		g[a][b]=g[b][a]=c;
    		e[a].push_back(b);
    		e[b].push_back(a);
    	}
    	for(int i=1;i<=n;++i)
    		scanf("%d",w+i);
    }
    
    void spfa()
    {
    	fill(pre,pre+n+1,-1);
    	fill(d+1,d+n+1,INF);
    	queue<int>q;
    	q.push(1);
    	d[1]=0;
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=0;i<e[u].size();++i){
    			int v=e[u][i];
    			if(d[v]>d[u]+g[u][v]){
    				d[v]=d[u]+g[u][v];
    				pre[v]=u;
    				q.push(v);
    			}
    		}
    	}
    }
    
    void dfs(int u,int fa)
    {
    	fill(dp[u],dp[u]+m+1,w[u]);
    	for(int i=0;i<e[u].size();++i){
    		int v=e[u][i];
    		if(v==fa) continue;
    		dfs(v,u);
    		
    		int t=2*g[u][v];
    		
    		for(int j=m;j>=t;--j)
    			for(int k=0;k+t<=j;++k)
    				dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k-t]);
    	}
    }
    
    void solve()
    {
    	spfa();
    	if(d[n]>m){
    		printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!
    ");
    	}else{
    		int u=n;
    		while(pre[u]!=-1){
    			g[pre[u]][u]=g[u][pre[u]]=0;
    			u=pre[u];
    		}
    		m-=d[n];
    		dfs(1,-1);
    		printf("%d
    ",dp[1][m]);
    	}
    }
    
    int main()
    {
    	while(~scanf("%d%d",&n,&m))
    	{
    		init();
    		solve();
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    前端-【学习心得】-事件委托方法
    [方法] iOS时间戳的转换
    [封装] 修改NSString中部分字段的颜色
    Python3基础16——file对象测试数据的读写与操作
    Python3基础15—— 变量作用域
    Python3基础14——函数&内置函数
    Python3基础13——冒泡排序
    Python3基础12——while循环
    Python3基础11——打印三角形
    Python3基础10——切片(str和list)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5372068.html
Copyright © 2011-2022 走看看