题意:有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;
}