当前位置: 首页 > news >正文

【蓝桥杯冲冲冲】k 短路 / [SDOI2010] 魔法猪学院

蓝桥杯备赛 | 洛谷做题打卡day33

文章目录

  • 蓝桥杯备赛 | 洛谷做题打卡day33
    • 题目背景
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
      • 数据规模
      • 数据更新日志
    • 题解代码
    • 我的一些话

  • 【模板】k 短路 / [SDOI2010] 魔法猪学院

    题目背景

    注:对于 k k k 短路问题,A* 算法的最坏时间复杂度是 O ( n k log ⁡ n ) O(nk \log n) O(nklogn) 的。虽然 A* 算法可以通过本题原版数据,但可以构造数据,使得 A* 算法在原题的数据范围内无法通过。事实上,存在使用可持久化可并堆的算法可以做到在 O ( ( n + m ) log ⁡ n + k log ⁡ k ) O((n+m) \log n + k \log k) O((n+m)logn+klogk) 的时间复杂度解决 k k k 短路问题。详情见 OI-Wiki。

    题目描述

    iPig 在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig 对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒 … \ldots

    iPig 今天就在进行一个麻烦的测验。iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量。作为 PKU 的顶尖学猪,让 iPig 用最少的能量完成从一种元素转换到另一种元素 … \ldots 等等,iPig 的魔法导猪可没这么笨!这一次,他给 iPig 带来了很多 1 1 1 号元素的样本,要求 iPig 使用学习过的魔法将它们一个个转化为 N N N 号元素,为了增加难度,要求每份样本的转换过程都不相同。这个看似困难的任务实际上对 iPig 并没有挑战性,因为,他有坚实的后盾 … \ldots 现在的你呀!

    注意,两个元素之间的转化可能有多种魔法,转化是单向的。转化的过程中,可以转化到一个元素(包括开始元素)多次,但是一但转化到目标元素,则一份样本的转化过程结束。iPig 的总能量是有限的,所以最多能够转换的样本数一定是一个有限数。具体请参看样例。

    输入格式

    第一行三个数 N , M , E N, M, E N,M,E,表示 iPig 知道的元素个数(元素从 1 1 1 N N N 编号),iPig 已经学会的魔法个数和 iPig 的总能量。

    后跟 M M M 行每行三个数 s i , t i , e i s_i, t_i, e_i si,ti,ei 表示 iPig 知道一种魔法,消耗 e i e_i ei 的能量将元素 s i s_i si 变换到元素 t i t_i ti

    输出格式

    一行一个数,表示最多可以完成的方式数。输入数据保证至少可以完成一种方式。

    样例 #1

    样例输入 #1

    4 6 14.9
    1 2 1.5
    2 1 1.5
    1 3 3
    2 3 1.5
    3 4 1.5
    1 4 1.5
    

    样例输出 #1

    3
    

在这里插入图片描述

提示

有意义的转换方式共 4 4 4 种:

1 → 4 1\to 4 14,消耗能量 1.5 1.5 1.5

1 → 2 → 1 → 4 1\to 2\to 1\to 4 1214,消耗能量 4.5 4.5 4.5

1 → 3 → 4 1\to3\to4 134,消耗能量 4.5 4.5 4.5

1 → 2 → 3 → 4 1\to2\to3\to4 1234,消耗能量 4.5 4.5 4.5

显然最多只能完成其中的 3 3 3 种转换方式(选第一种方式,后三种方式仍选两个),即最多可以转换 3 3 3 份样本。

如果将 E = 14.9 E=14.9 E=14.9 改为 E = 15 E=15 E=15,则可以完成以上全部方式,答案变为 4 4 4

数据规模

占总分不小于 10 % 10\% 10% 的数据满足 N ≤ 6 , M ≤ 15 N \leq 6,M \leq 15 N6,M15

占总分不小于 20 % 20\% 20% 的数据满足 N ≤ 100 , M ≤ 300 , E ≤ 100 N \leq 100,M \leq 300,E\leq100 N100,M300,E100 E E E 和所有的 e i e_i ei 均为整数(可以直接作为整型数字读入)。

所有数据满足 2 ≤ N ≤ 5000 2 \leq N \leq 5000 2N5000 1 ≤ M ≤ 200000 1 \leq M \leq 200000 1M200000 1 ≤ E ≤ 1 0 7 1 \leq E \leq 10 ^ 7 1E107 1 ≤ e i ≤ E 1 \leq ei\leq E 1eiE E E E 和所有的 e i e_i ei 为实数。

数据更新日志

  • 2010/xx/xx:原版数据;

  • 2018/03/02:@kczno1 添加了 一组数据;

  • 2018/04/20:@X_o_r 添加了 一组数据;

  • 2021/01/08:@LeavingZ 添加了 两组数据。

题解代码

学会利用新知,自己多试试并尝试积攒一些固定解答方案,debug,以下是题解代码 ~

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;template <class Num> inline void Cmax(Num &x, const Num y) {x = y > x ? y : x;
}template <class Num> inline void Cmin(Num &x, const Num y) {x = y < x ? y : x;
}const int maxn(5005);
const int maxm(2e5 + 5);
const double eps(1e-8);int n, m, first[maxn], cnt, vis[maxn], rt[maxn], tot, cov[maxm << 1], ans, fa[maxn];
double se, e, dis[maxn];
priority_queue < pair <double, int> > q;struct Heap {int ls, rs, dis, ed;double w;
} tr[maxm * 20];struct Edge {int to, next;double w;
} edge[maxm << 1];inline void Add(int u, int v, double w) {edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;edge[cnt] = (Edge){u, first[v], w}, first[v] = cnt++;
}inline int NewNode(double w, int ed) {int x = ++tot;tr[x].w = w, tr[x].dis = 1, tr[x].ed = ed;return x;
}int Merge(int x, int y) {if (!x || !y) return x + y;if (tr[x].w - tr[y].w >= eps) swap(x, y);int p = ++tot;tr[p] = tr[x], tr[p].rs = Merge(tr[p].rs, y);if (tr[tr[p].ls].dis < tr[tr[p].rs].dis) swap(tr[p].ls, tr[p].rs);tr[p].dis = tr[tr[x].rs].dis + 1;return p;
}void Dfs(int u) {vis[u] = 1;for (int e = first[u], v; e != -1; e = edge[e].next)if (e & 1) {double w = edge[e].w;if (fabs(dis[u] + w - dis[v = edge[e].to]) < eps && !vis[v])fa[v] = u, cov[e ^ 1] = 1, Dfs(v);}
}int main() {memset(first, -1, sizeof(first));memset(dis, 127, sizeof(dis));scanf("%d%d%lf", &n, &m, &se);for (int i = 1, u, v; i <= m; ++i) scanf("%d%d%lf", &u, &v, &e), Add(u, v, e);dis[n] = 0, q.push(make_pair(0, n));while (!q.empty()) {int u = q.top().second;q.pop();if (vis[u]) continue;vis[u] = 1;for (int e = first[u]; ~e; e = edge[e].next)if (e & 1) {int v = edge[e].to;if (dis[v] - (dis[u] + edge[e].w) >= eps)q.push(make_pair(-(dis[v] = dis[u] + edge[e].w), v));}}for (int i = 1; i <= n; ++i) vis[i] = 0;Dfs(n);for (int e = 0, u, v; e < cnt; e += 2)if (!cov[e]) {u = edge[e ^ 1].to, v = edge[e].to;if (dis[u] == dis[0] || dis[v] == dis[0]) continue;rt[u] = Merge(rt[u], NewNode(dis[v] + edge[e].w - dis[u], v));}for (int i = 1; i <= n; ++i) q.push(make_pair(-dis[i], i));for (int i = 1, u; i <= n; ++i) {u = q.top().second, q.pop();if (fa[u]) rt[u] = Merge(rt[u], rt[fa[u]]);}if (dis[1] - se < eps) se -= dis[1], ++ans;if (rt[1]) q.push(make_pair(-tr[rt[1]].w, rt[1]));while (!q.empty()) {int ed = q.top().second;double cur = q.top().first, w = dis[1] - cur;if (w - se >= eps) break;q.pop(), se -= w, ++ans;for (int i = 0; i < 2; ++i) {int nxt = i ? tr[ed].rs : tr[ed].ls;if (nxt) q.push(make_pair(cur + tr[ed].w - tr[nxt].w, nxt));}if (rt[tr[ed].ed]) q.push(make_pair(cur - tr[rt[tr[ed].ed]].w, rt[tr[ed].ed]));}printf("%d\n", ans);return 0;
}

我的一些话

  • 今天学习动态规划,dp属于比较难的部分,这题利用记忆化搜索即可快速解决,需要多动脑,多思考思路还是很好掌握的,虽然一次性AC有一定难度,需要通盘的考虑和理解,以及扎实的数据结构基础才能独立写出AC代码。但无论难易,大家都要持续做题,保持题感喔!一起坚持(o´ω`o)

  • 如果有非计算机专业的uu自学的话,关于数据结构的网课推荐看b站上青岛大学王卓老师的课,讲的很细致,有不懂都可以私信我喔

  • 总结来说思路很重要,多想想,多在草稿纸上画画,用测试数据多调试,debug后成功编译并运行出正确结果真的会感到很幸福!

  • 关于之前蓝桥杯备赛的路线和基本方法、要掌握的知识,之前的博文我都有写,欢迎大家关注我,翻阅自取哦~

  • 不管什么都要坚持吧,三天打鱼两天晒网无法形成肌肉记忆和做题思维,该思考的时候一定不要懈怠,今天就说这么多啦,欢迎评论留言,一起成长:)

相关文章:

  • 2.9日学习打卡----初学RabbitMQ(四)
  • 双指针-two pointers的应用
  • C++笔记之regex(正则表达式)
  • 线性表的插入
  • 移动端web开发布局
  • Spring Boot项目整合Seata AT模式
  • Electron基本介绍
  • Oracle数据表ID自增操作
  • 【附代码】NumPy加速库NumExpr(大数据)
  • 微信小程序上传代码教程
  • C#,十进制展开数(Decimal Expansion Number)的算法与源代码
  • linux查看当前连接的IP
  • 新版MQL语言程序设计:键盘快捷键交易的设计与实现
  • 【大厂AI课学习笔记】1.5 AI技术领域(1)计算机视觉
  • 【安卓操作系统——讲解】
  • Bytom交易说明(账户管理模式)
  • Druid 在有赞的实践
  • LeetCode算法系列_0891_子序列宽度之和
  • Lsb图片隐写
  • swift基础之_对象 实例方法 对象方法。
  • uva 10370 Above Average
  • 诡异!React stopPropagation失灵
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前嗅ForeSpider教程:创建模板
  • 如何实现 font-size 的响应式
  • 推荐一个React的管理后台框架
  • 小试R空间处理新库sf
  • 译有关态射的一切
  • elasticsearch-head插件安装
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​水经微图Web1.5.0版即将上线
  • (1)(1.13) SiK无线电高级配置(六)
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (javascript)再说document.body.scrollTop的使用问题
  • (Matlab)使用竞争神经网络实现数据聚类
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (四) Graphivz 颜色选择
  • (算法)N皇后问题
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)appium-desktop定位元素原理
  • .gitignore文件_Git:.gitignore
  • .NET Framework杂记
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET性能优化(文摘)
  • @Builder用法
  • @Import注解详解
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • []T 还是 []*T, 这是一个问题
  • [AIGC] 如何建立和优化你的工作流?
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [C/C++]数据结构 循环队列