原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4276

目录

  • 题意
  • 分析
  • Code

题意

有一棵树,每个节点都有财富wi,每条边都会花费ci的时间,问你有T的时间,从节点1出发到节点n出口最多可以拿走多少宝物。

分析

非常明显的树形背包的模型,列出状态 f [ i ] [ j ] f[i][j] f[i][j]代表第i个节点及其子树花费j的时间最多取到的财富总和,那么状态转移的方程可以轻松写出 f [ u ] [ j ] = m a x ( f [ u ] [ j ] , f [ j − k − c o s t ] + f [ v ] [ k ] ) f[u][j]=max(f[u][j], f[j-k-cost]+f[v][k]) f[u][j]=max(f[u][j],f[j−k−cost]+f[v][k])

接着就是分类考虑当前取的边是否在最短路径上,因为根据树的性质,两点之间的路径是唯一的,因此我们一定会取一遍最短路径上的财富,我们直接跑一遍最短路将最短路径上的边权改为0。如果当前的边不在最短路径上,那么cost要乘2,因为肯定要走两遍当前边。

Code

#include <bits/stdc++.h>
using namespace std;
//#define ACM_LOCAL
#define re register
#define fi first
#define se second
#define please_AC return 0
const int N = 2000 + 10;
const int M = 5e6 + 10;
const int INF = 1e9;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
int n, m, cnt;
int dp[105][505], h[N], val[N], dis[N], vis[N], pre[N], rnk[N];
struct Edge {int to, next, w;
}e[M];
void add(int u, int v, int w) {e[cnt].to = v;e[cnt].w = w;e[cnt].next = h[u];h[u] = cnt++;
}
struct node {int d, now;bool operator < (const node &rhs) const {return d > rhs.d;}
};
void dij(int st) {priority_queue<node> q;memset(dis, 0x3f, sizeof dis);memset(vis, 0, sizeof vis);memset(pre, 0, sizeof pre);dis[st] = 0; q.push({0, st});while (q.size()) {int now = q.top().now;q.pop();if (vis[now]) continue;vis[now] = 1;for (int i = h[now]; ~i; i = e[i].next) {int v = e[i].to;if (dis[v] > dis[now] + e[i].w) {dis[v] = dis[now] + e[i].w;pre[v] = now;rnk[v] = i;if (!vis[v]) q.push({dis[v], v});}}}int now = n;while(now != 1) {e[rnk[now]].w = e[rnk[now] ^ 1].w = 0;now = pre[now];}
}
void dfs(int x, int fa) {for (int i = 0; i <= m; i++) dp[x][i] = val[x];for (int i = h[x]; ~i; i = e[i].next) {int v = e[i].to;if (v == fa) continue;dfs(v, x);for (int j = m; j >= e[i].w*2; j--) {for (int k = 0; k + e[i].w * 2 <= j; k++) {dp[x][j] = max(dp[x][j], dp[x][j-k-2*e[i].w] + dp[v][k]);}}}
}
void solve() {while(scanf("%d%d", &n, &m) != EOF) {memset(h, -1, sizeof h); cnt = 0;memset(dp, 0, sizeof dp);for (int i = 1; i <= n-1; i++) {int u, v, w; cin >> u >> v >> w;add(u, v, w), add(v, u, w);}for (int i = 1; i <= n; i++) cin >> val[i];dij(1);if (dis[n] > m) {printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");continue;}m -= dis[n];dfs(1, 0);printf("%d\n", dp[1][m]);}
}signed main() {#ifdef ACM_LOCALios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#endifsolve();please_AC;
}

HDU 4276 The Ghost Blows Light 最短路+树形背包相关推荐

  1. HDU 4276 The Ghost Blows Light(树形DP)

    题意:给出一棵无向树,从1走到n,总时间为T,每走一条边需要花费一定时间,每个结点有一定权值,问在指定时间内到达n点能获取的最大权值. 由于已经到过的点能再次返回(虽然不能再次获得该点权值),情况数倍 ...

  2. hdu 4276 The Ghost Blows Light(树型DP)

    题意:给出一棵树,走过每条边都要花费时间,每个点有一定价值的物品.求在给定时间内能不能从1走到n,如果能,最多可以带走多少价值的物品. 思路:首先对树进行一遍搜索,看能不能从1走到n,如果不能直接输出 ...

  3. HDU4276(The Ghost Blows Light T时间入口1 出口n 问可得的最大价值 树形dp)

    题目 题意: 你在一座古墓里盗墓,古墓在T分钟时就会倒塌,你就挂了.古墓有n个房间,每个房间都有一定价值的宝藏,n-1条边,每条边有花费的时间,形成一棵树.如果逃不出去就输出- 如果能逃出去,那么输出 ...

  4. 【HDU4276】The Ghost Blows Light

    题目大意:给定一棵有根树,1 号节点为根节点,点有点权,边有边权,初始给定一个价值,每经过一条边都会减少该价值,每经过一个点都会增加相应的答案贡献值,求如何在给定价值的情况下最大化答案贡献,并要求最后 ...

  5. 【HDU - 1561】The more, The Better(树形背包,dp,依赖背包问题与空间优化,tricks)

    题干: ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城 ...

  6. 【HDU - 2112】 HDU Today(dijkstra单源最短路 + map转换)

    题干: HDU Today Time Limit : 15000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  7. hdu 2066 一个人的旅行(最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2066 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里 ...

  8. HDU 2066-一个人的旅行(最短路Dijkstra)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  9. HDU 3339 In Action 最短路+01背包

    题目链接: 题目 In Action Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

最新文章

  1. 点到点链路上的ospf
  2. 如何添加团队成员,并为团队成员分配访问权限(转载)
  3. MySQL通过添加索引解决线上数据库服务器压力大问题
  4. plantuml 方法图_UML与软件建模:第四次作业(学习PlantUML活动图绘制方法)
  5. redis 端口_「建议收藏」手把手教你搭建redis集群
  6. 软件工程(2018)第3次团队作业
  7. 跨平台 App 开发引擎 CrossApp
  8. Word如何插入图片
  9. C语言汉字在内存中如何存储
  10. python中rename函数_Python3 os.rename() 方法
  11. python爬虫之xpath解析(附实战)
  12. Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day18】—— 奇葩问题合集
  13. 做个合格的吃货~利用Python爬取美食网站3032个菜谱并分析
  14. jmeter 接口请求出现安全验证解决方案
  15. 二叉树的镜像(递归非递归)
  16. 我推荐这几个好玩有趣的小网站
  17. 从《虎嗅》改版说说小作坊如何做产品和项目管理
  18. QML之Canvas实现标尺(刻度尺)方案
  19. 微信小程序使用weapp-qrcode生成二维码
  20. n行Python代码系列专栏文章目录

热门文章

  1. ​揭秘!折叠屏幕如何制作而成?
  2. 荣耀10GT AIS手持超级夜景样张解析,拍照最Skr的手机!
  3. xml文件写入mysql数据库_将XML文件插入到数据库
  4. E-Leaning简介
  5. 妹子的陌陌_MISC
  6. vscode pylint 配置
  7. 图文手把手教程--ESP32 一键配网(Smartconfig、Airkiss)
  8. win10家庭版设置移动热点出现“我们无法设置移动热点”
  9. 请大家交流一下购买房子注意事项
  10. 被讨厌的勇气:目的论