标签:
题意:
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