题意:有n(n<=100)个点的树,每个点有固定的val值,走每条边需要花费固定的时间,问Hu Bayi能否从1在给定的时间范围内走到n(n点为出口),
如果不能输出"Human beings die in pursuit of wealth, and birds die in pursuit of food!",如果能输出在所经过的路径上能得到的最大val和。
题解:树形dp,首先DFS得出从1->n路径上的权值和tot,并将路径上的权值置0,这样能够保证从1->n的路径始终是通的,然后进行树形dp+01背包即可。
Sure原创,转载请注明出处。
#include <iostream> #include <cstdio> #include <memory.h> #define MAX(a , b) ((a) > (b) ? (a) : (b)) using namespace std; const int maxn = 102; const int maxm = 502; struct node { int v,w; int next; }edge[maxn << 1]; int head[maxn],val[maxn],dp[maxn][maxm]; bool vis[maxn]; int m,n,idx,tot; void init() { memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); idx = tot = 0; return; } void addedge(int u,int v,int w) { edge[idx].v = v; edge[idx].w = w; edge[idx].next = head[u]; head[u] = idx++; edge[idx].v = u; edge[idx].w = w; edge[idx].next = head[v]; head[v] = idx++; return; } void read() { int u,v,w; for(int i=1;i<n;i++) { scanf("%d %d %d",&u,&v,&w); addedge(u,v,w); } for(int i=1;i<=n;i++) { scanf("%d",&val[i]); } return; } void DFS(int st,int pre) { if(st == n) { vis[st] = true; } for(int i=head[st];i != -1;i=edge[i].next) { if(edge[i].v == pre) continue; DFS(edge[i].v , st); if(vis[edge[i].v]) { vis[st] = true; tot += edge[i].w; edge[i].w = edge[i^1].w = 0; } } return; } void dfs(int st,int pre) { int v = -1; for(int i=head[st];i != -1;i=edge[i].next) { if(edge[i].v == pre) continue; if(vis[edge[i].v]) { v = edge[i].v; continue; } dfs(edge[i].v , st); for(int j=m;j>=edge[i].w * 2;j--) { for(int k=0;k + edge[i].w * 2 <= j;k++) { dp[st][j] = MAX(dp[st][j] , dp[st][j-edge[i].w * 2 - k] + dp[edge[i].v][k]); } } } if(v != -1) { for(int i=0;i<=m;i++) { dp[v][i] = dp[st][i] + val[v]; } dfs(v , st); } return; } void solve() { DFS(1,0); if(tot > m) { puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!"); return; } m -= tot; for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) { dp[i][j] = val[i]; } } dfs(1,0); printf("%d\n",dp[n][m]); return; } int main() { while(~scanf("%d %d",&n,&m)) { init(); read(); solve(); } return 0; }