您的位置:首页 > 其它

HDU 4276 The Ghost Blows Light (树形DP)

2015-04-15 19:51 483 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4276

题意:给一棵树,每个点都有点权,走过一条边需要时间,然后给时间T,问能否从1点走到N点,如果能走到,输出所获得的最大权值

思路:先找出1到N的路径并算出时间花费,对于其他点进行树形DP,dp[u][t]代表从u点走花费t时间所能获得的最大权值

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <utility>
#include <functional>
#include <algorithm>
#include <string>
#include <queue>
#include <cctype>
#include <set>

using namespace std;

const int maxn = 110;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int n, t, cnt, sum;
int head[maxn], val[maxn];
int dp[maxn][550];

struct edge
{
int to, nxt, w;
} e[maxn << 1];

void init()
{
sum = cnt = 0;
memset(head, -1, sizeof(head));
}

void add(int u, int v, int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt++;
}

bool dfs(int u, int fa)
{
if (u == n) return true;
for (int i = head[u]; ~i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa) continue;
if (dfs(v, u))
{
sum += e[i].w;
e[i].w = 0;
return true;
}
}
return false;
}

void ddfs(int u, int fa)
{
for (int i = 0; i <= t; i++)
dp[u][i] = val[u];
for (int i = head[u]; ~i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa) continue;
ddfs(v, u);
int w = e[i].w * 2;
for (int ti = t; ti >= w; ti--)
{
for (int j = 0; j <= ti - w; j++)
dp[u][ti] = max(dp[u][ti], dp[v][j] + dp[u][ti - j - w]);
}
}
}

int main()
{
while (~scanf("%d%d", &n, &t))
{
init();
for (int i = 1; i < n; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
for (int i = 1; i <= n; i++)
scanf("%d", &val[i]);
dfs(1, -1);
if (t < sum)
{
puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
continue;
}
t -= sum;
ddfs(1, -1);
cout << dp[1][t] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: