【蓝桥杯冲冲冲】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后成功编译并运行出正确结果真的会感到很幸福!

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/382419.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第9章 智能租房——详情页

学习目标 掌握详情页房源数据展示功能的逻辑&#xff0c;能够实现在详情页上展示基本信息和配套设施 了解数据可视化&#xff0c;能够说出数据可视化的概念和流程 熟悉ECharts的用法和配置项&#xff0c;能够通过ECharts绘制常用图表&#xff0c;并为图表添加配置项 掌握户型…

2024年 前端JavaScript入门到精通 第一天

主要讲解JavaScript核心知识&#xff0c;包含最新ES6语法&#xff0c;从基础到API再到高级。让你一边学习一边练习&#xff0c;重点知识及时实践&#xff0c;同时每天安排大量作业&#xff0c;加深记忆&#xff0c;巩固学习成果。 1.1 基本软件与准备工作 1.2 JavaScript 案例 …

前端开发_AJAX基本使用

AJAX概念 AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。 简单点说&#xff0c;就是使用XMLHttpRequest对象与服务器通信。 它可以使用JSON&#xff0c;XML&#xff0c;HTML和text文本等格式发送和接收数据。 AJAX最吸引人的就是它的“异步"特性&am…

python-分享篇-GUI界面开发-PyQt5-对QListWidget表格进行数据绑定

代码 # -*- coding: utf-8 -*-# Form implementation generated from reading ui file bindtable.ui # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! 对QTableWidget表格进行数据绑定from PyQt5 import QtCore, Q…

Wireshark不显示Thrift协议

使用Wireshark对thrift协议进行抓包&#xff0c;但是只显示了传输层的tcp协议&#xff1a; "右键" -> "Decode As" 选择thrift的tcp端口 将“当前”修改为Thrift&#xff0c;然后点击“确定” 设置后&#xff0c;可以发现Wireshark里面显示的协议从Tcp变…

正版软件 - Proxyman:让网络调试变得更智能、更高效

在软件开发的世界里&#xff0c;网络调试一直是开发者和测试工程师的痛点。传统的调试工具往往操作复杂&#xff0c;界面不够直观&#xff0c;而且性能上也难以满足现代应用的需求。今天&#xff0c;我要向大家介绍一款名为Proxyman的网络调试工具&#xff0c;它以其简洁的界面…

第十八篇【传奇开心果短博文系列】Python的OpenCV库技术点案例示例:图像修复和恢复

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例系列短博文目录前言一、常用的图像修复与恢复技术二、插值方法示例代码三、基于纹理合成的方法示例代码四、基于边缘保持的方法示例代码五、基于图像修复模型的方法示例代码六、基于深度学习的方法示例代码七…

Vulnhub靶机:hacksudo-search

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;hacksudo-search&#xff08;10.0.2.50&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.co…

【leetcode热题100】 格雷编码

n 位格雷码序列 是一个由 2n 个整数组成的序列&#xff0c;其中&#xff1a; 每个整数都在范围 [0, 2n - 1] 内&#xff08;含 0 和 2n - 1&#xff09;第一个整数是 0一个整数在序列中出现 不超过一次每对 相邻 整数的二进制表示 恰好一位不同 &#xff0c;且第一个 和 最后一…

c语言游戏实战(4):人生重开模拟器

前言&#xff1a; 人生重开模拟器是前段时间非常火的一个小游戏&#xff0c;接下来我们将一起学习使用c语言写一个简易版的人生重开模拟器。 网页版游戏&#xff1a; 人生重开模拟器 (ytecn.com) 1.实现一个简化版的人生重开模拟器 &#xff08;1&#xff09; 游戏开始的时…

Python算法题集_随机链表的复制

Python算法题集_随机链表的复制 题138&#xff1a;随机链表的复制1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【双层循环】2) 改进版一【字典哈希】3) 改进版二【单层哈希】4) 改进版三【递归大法】 4. 最优算法 本文为Python算法题集之一的…

Python 错误及其解决方法

Python 是一种易于学习的编程语言&#xff0c;但初学者在学习和使用 Python 的过程中难免会遇到一些错误。以下是一些常见的 Python 错误及其解决方法&#xff1a; 1. 语法错误&#xff08;SyntaxError&#xff09;&#xff1a; python # 错误示例 print("Hello, World!…

elasticsearch下载及可视化工具下载使用

elasticsearch下载及配置、启动 一、下载 Download Elasticsearch | Elastic 二、启动 双击bat即可。 出现如下说明启动成功&#xff1a; 访问测试&#xff1a; 三、注意 &#xff08;1&#xff09;因为es启动默认端口是&#xff1a;9200,所以需要检查此端口是否被占用。…

js中bind、call、apply 区别(如何实现)

文章目录 一、作用二、区别applycallbind小结 三、实现 一、作用 call、apply、bind作用是改变函数执行时的上下文&#xff0c;简而言之就是改变函数运行时的this指向 那么什么情况下需要改变this的指向呢&#xff1f;下面举个例子 var name "lucy"; var obj {n…

python统计分析——两样本t检验

参考资料&#xff1a;用python动手学统计学 1、导入库 # 导入库 # 用于数值计算的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 用于绘图的库 from matplotlib import pyplot as plt import seaborn as sns sns.set() 2、准备数…

【HTTP】localhost和127.0.0.1的区别是什么?

目录 localhost是什么呢&#xff1f; 从域名到程序 localhost和127.0.0.1的区别是什么&#xff1f; 域名的等级划分 多网站共用一个IP和端口 私有IP地址 IPv6 今天在网上逛的时候看到一个问题&#xff0c;没想到大家讨论的很热烈&#xff0c;就是标题中这个&#xff1a; …

基于微信小程序的校园故障维修管理系统的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

闭区间上连续函数的性质【高数笔记】

1. 分几个性质 2. 每个性质的注意事项是什么 3. 每个性质适用什么类型的题型 4. 注意最值定理和正弦函数的不同 5. 做题步骤是什么

使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook&#xff0c;并结合cpolar内网穿透…

异地的文件如何共享?

在现代工作中&#xff0c;随着互联网的普及和信息化的进步&#xff0c;越来越多的人需要在异地进行文件共享和协同办公。无论是企业的异地分支机构&#xff0c;还是多个个人之间的跨地合作&#xff0c;通过异地的文件共享可以极大地提高工作效率和协作效果。本文将介绍一种名为…