码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4276-The Ghost Blows Light(树状背包)

时间:2015-08-03 12:50:01      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:

题意:

n个房间,每个有一定的钱,一个房间到另一个房间花费一定的时间,给你房间连接树,求在t时间内到达房间m能得到的最大钱数(从房间1(根)出发)

分析:

该题关键是最后要到达m,没有这个条件,就是基础的树形背包,哎,一开始没思路,放了一段时间,看看题解才明白,该题突破口,就是,你先想怎么判断不能到到达m的情况,自然想到最短路,对树先求一次最短路,在最短路上的点只能,过一次,其他得点过两次,把最短路上的点花费置零,剩下的就是基础的树形背包。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int>p;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 1<<20;
const int mod =  1000000007;
int d[110],dp[110][510],head[110],n,t,len;
int par[110];
struct edge{
int st,en,c,next;
}e[310];
void add(int a,int b,int c)
{
    e[len].st=a;
    e[len].en=b;
    e[len].c=c;
    e[len].next=head[a];
    head[a]=len++;
}
//求最短路
int dijkstra(int s){
     priority_queue<p,vector<p>,greater<p> >q;
     for(int i=1;i<=n;++i)
        d[i]=INF;
        q.push(p(0,s));
         d[s]=0;
    memset(par,-1,sizeof(par));
    edge a,b;
    while(!q.empty()){
        p a=q.top();
        q.pop();
        int j=a.second;
        int cost=a.first;
        if(d[j]<cost)continue;
     for(int i=head[j];i!=-1;i=e[i].next){
            edge g=e[i];
            if(d[g.en]>cost+g.c){
                par[g.en]=i;
                d[g.en]=cost+g.c;
                q.push(p(d[g.en],g.en));
            }
     }
    }
    //最短路上的点置零
    for(int i=n;i!=s;i=e[par[i]].st){
        e[par[i]].c=0;
        e[par[i]^1].c=0;
    }
    return d[n];
}
int used[110];
void dfs(int root){
    used[root]=1;
    for(int i=head[root];i!=-1;i=e[i].next){
        int son=e[i].en;
        int cost=e[i].c*2;//走两次
        if(used[son])continue;
        dfs(son);
        for(int j=t;j>=cost;--j){
            for(int k=0;k+cost<=j;++k){
                dp[root][j]=max(dp[root][j],dp[root][j-k-cost]+dp[son][k]);
            }
        }
    }
}
int main()
{
    int a,b,c;
    while(~scanf("%d%d",&n,&t)){
            memset(dp,0,sizeof(dp));
            memset(head,-1,sizeof(head));
            memset(used,0,sizeof(used));
            len=0;
        for(int i=0;i<n-1;++i){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        for(int i=1;i<=n;++i){
            scanf("%d",&dp[i][0]);
        }
        t-=dijkstra(1);
        int maxv=0;
        if(t<0)printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
        else{
                dfs(1);
            for(int i=0;i<=t;++i)
                maxv=max(maxv,dp[1][i]);
            printf("%d\n",maxv);
        }
    }
return 0;

 

HDU 4276-The Ghost Blows Light(树状背包)

标签:

原文地址:http://www.cnblogs.com/zsf123/p/4698916.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!