SPFA+队列优化与迪杰斯特拉+优先队列(最小堆优化)解一道水题

Dijkstra算法朴素版&堆优化详解(单源最短路问题) Dijkstra算法朴素版&堆优化详解(单源最短路问题) 迪杰斯特拉算法主要特点是从起始点开始,采用贪心策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。 阅读详情

其实算法还是挺有意思的,可惜我年纪大了,搞不动了,这种东西应该适合在中学时候搞。。

题目:

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40

题意:英文比较简单,不翻译了,就是给一个图,有距离有边权,求最短路径而且不唯一时输出边权唯一的路径。

解答:方法一:SPFA+队列优化,具体百度。只讲边权如何处理,在最短距离相同时候去看权值大小比较得出结果,如果更优,则更新,同时用一个数组存下每个节点的路径前驱,每次更新时候不要忘记更新。

​#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string.h>
using namespace std;
const int MAXN = 505;
vector<pair<int, int>> E[MAXN];
int n, m;
int d[MAXN];
int inq[MAXN] = {0};
int pre[MAXN];
int costMin[MAXN];
vector<pair<int, int> > cost[MAXN];
int main() {
	int s, t;
	scanf("%d%d%d%d", &n, &m, &s, &t);
	fill(d, d + n, 1e9);
	fill(costMin, costMin + n, 1e9);
	for (int i = 0; i < m; i++) {
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		E[a].push_back( make_pair(b,c));
		E[b].push_back(make_pair(a, c));
		cost[a].push_back(make_pair(b, d));
		cost[b].push_back(make_pair(a, d));
	}
	queue<int> Q;
	Q.push(s);
	d[s] = 0;
	costMin[s] = 0;
	inq[s] = 1;
	while (!Q.empty()) {
		int now = Q.front();
		Q.pop();
		inq[now] = 0;
		for (int i = 0; i < E[now].size(); i++) {
			int v = E[now][i].first;
			if (d[v] > d[now] + E[now][i].second) {
				if (inq[v] == 1)continue;
				d[v] = d[now] + E[now][i].second;
				costMin[v] = costMin[now] + cost[now][i].second;
				pre[v] = now;
				inq[v] = 0;
				Q.push(v);
			}
			else if (d[v] == d[now] + E[now][i].second) {
				if (costMin[now] + cost[now][i].second < costMin[v]) {
					costMin[v] = costMin[now] + cost[now][i].second;
					pre[v] = now;
				}
			}
		}
	}
	vector<int> tempPath;
	int ttt = t;
	tempPath.push_back(t);
	while (ttt != s) {
		ttt = pre[ttt];
		tempPath.push_back(ttt);
	}
	for (int i = tempPath.size() - 1; i >= 0; i--) {
		printf("%d ", tempPath[i]);
	}
	printf("%d %d\n", d[t], costMin[t]);
	return 0;
}

方法二:迪杰斯特拉+优先队列

和上面基本一样,就是用的方法不一样,基本上就改改就好了

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string.h>
using namespace std;
const int MAXN = 505;
vector<pair<int, int>> E[MAXN];
int n, m;
int d[MAXN];
int pre[MAXN];
int costMin[MAXN];
vector<pair<int, int> > cost[MAXN];
int main() {
	int s, t;
	scanf("%d%d%d%d", &n, &m, &s, &t);
	fill(d, d + n, 1e9);
	fill(costMin, costMin + n, 1e9);
	for (int i = 0; i < m; i++) {
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		E[a].push_back( make_pair(b,c));
		E[b].push_back(make_pair(a, c));
		cost[a].push_back(make_pair(b, d));
		cost[b].push_back(make_pair(a, d));
	}
	priority_queue<pair<int, int>> Q; d[s] = 0;
	Q.push(make_pair(-d[s], s));// 小顶堆返回最小
	costMin[s] = 0;
	while (!Q.empty()) {
		int now = Q.top().second;
		Q.pop();
		for (int i = 0; i < E[now].size(); i++) {
			int v = E[now][i].first;
			if (d[v] > d[now] + E[now][i].second) {
				d[v] = d[now] + E[now][i].second;
				costMin[v] = costMin[now] + cost[now][i].second;
				pre[v] = now;
				Q.push(make_pair(-d[v], v));
			}
			else if (d[v] == d[now] + E[now][i].second) {
				if (costMin[now] + cost[now][i].second < costMin[v]) {
					costMin[v] = costMin[now] + cost[now][i].second;
					pre[v] = now;
				}
			}
		}
	}
	vector<int> tempPath;
	int ttt = t;
	tempPath.push_back(t);
	while (ttt != s) {
		ttt = pre[ttt];
		tempPath.push_back(ttt);
	}
	for (int i = tempPath.size() - 1; i >= 0; i--) {
		printf("%d ", tempPath[i]);
	}
	printf("%d %d\n", d[t], costMin[t]);
	return 0;
}

总结:当然了,最后找路径用DFS也是可以的,看个人喜好,反正吧,最短路如果这两种还不行。。别的方法应该是没什么希望了。反正就这样了,如果要负环的话,那就SPFA,没有就无脑迪杰斯特拉。

【算法】单源最短路径——dijkstra算法 一,概念 单源最短路径 给定一个带权有向图G=(V,E),其中每条边的权是一个实数。另外,还给定V中的一个顶点,称为源。要计算从源到其他所有各顶点的最短路径长度。这里的长度就是指路上各边权之和。这个问题通常称为单源最短路径问题。 dijkstra算法简介 迪杰斯特拉算法(Dijkstra),是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。 需要注意的是,dij 阅读详情

相关推荐

最短路 ( dijkstra floyd spfa Bellman_Ford 堆优化Dijkstra(优先队列))

dijkstra (不能判负权 也不能判负环) dis数组里面存的是n到起点的最短距离 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M&...

ZCY的博客 473

算法系列——SPFA算法(贝尔曼-福特算法的队列优化形式)

本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节。我在努力! 本篇文章编程语言为Python,供参考。 SPFA算法(贝尔曼-福特算法的队列优化形式) 用于负权图中计算一个节点到其他节点的最短路径。(Bellman-Ford算法的一种优化形式) 基本原理:建立一个队列,逐次用队首结点u对与之相连的全部结点v进行松弛操作,如果结点v的最短路径距离更新,且v不在队列中, 则加入队列,直到队列为空停止。 1. 算法实现 附全部源码: #北...

lzh1366的博客 1447

堆优化的dijkstra算法(dijkstra+邻接表+heap)

用堆优化的dijkstra,接口为邻接链表。

POJ1722二维spfa+优先队列优化

题意:      给你一个有向图,然后求从起点到终点的最短,但是还有一个限制,就是总花费不能超过k,也就是说每条边上有两个权值,一个是长度,一个是花费,求满足花费的最短长度。 思路:       一开始写了一个mark[i][j]第i个点花费j状态的spfa,TLE了,然后又优化了下,就是先反向搜索一遍简单最短路(以花费为权值)然后用这个结果在mark[][]二维的最短路里面剪枝用,

天使也掉毛 1064

从PLC到机械臂:揭秘工业自动化中的信号交互与控制逻辑

本文深入解析了PLC与机械臂在工业自动化中的信号交互与控制逻辑,详细介绍了硬件连接方案、通信机制及控制逻辑设计。通过西门子PLC与六轴机械臂的实战案例,展示了从信号采集到动作执行的完整流程,并探讨了高级控制策略与行业应用前景,为工程师提供了一套完整的实践框架。

weixin_29304985的博客 388

Hermes Dashboard Web 端部署完整说明

通过反向代理(nginx)使用公网域名访问时,会遇到 Host 头校验、CORS 跨域、WebSocket 连接拒绝三个核心问题。本文档记录了完整的源码修改方案和部署步骤。确保 nginx 主配置加载了 WebSocket map(宝塔默认为。路径的公开访问(无需登录),其他路径仍受 Cookie 认证保护。Hermes Dashboard 默认绑定。访问站点时会先弹出浏览器密码框,输入用户。在 nginx 反向代理配置中的。环境变量动态读取允许的域名。nginx 配置中已添加。

大白菜代码的博客 801

贝尔曼算法队列优化(SPFA)

最短路问题 想必大家接触图论的时候,结束了DFS和BFS,接下来就是求最短路了吧!在学SPFA之前,你也许已经接触过弗洛伊德算法和迪杰斯特拉算法,甚至还学过贝尔曼算法,然而,不管你以前学过什么,今天的SPFA都可以向你保证——零基础学会! 言归正传,话回正题。 什么是最短路问题呢?就是求两点之间的最短路,当然是一个带权图(没权值的图还最短?)。然而SPFA是由贝尔曼改良过来的,所以这也是单源最短路...

Martisum的博客 583

保姆级教程:在Ubuntu 22.04上用VLLM+OpenWebUI部署DeepSeek-R1-14B(含Q8量化模型下载)

本文提供在Ubuntu 22.04上使用VLLM和OpenWebUI部署DeepSeek-R1-14B大语言模型的完整教程,包括环境配置、模型下载、VLLM参数调优及OpenWebUI集成。特别针对Q8量化模型优化部署流程,解决CUDA版本冲突等常见问题,适合开发者快速搭建本地AI对话系统。

weixin_26712075的博客 430

SPFA 算法详解( 强大图解,不会都难!)&&spfa优化——深度优先搜索dfs

https://blog.youkuaiyun.com/muxidreamtohit/article/details/7894298  适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回...

sxy201658506207的博客 5万+

某知名系统漏洞挖掘与利用思路探索

本文以安全研究为目的,分享对该套系统的代码审计和漏洞挖掘过程,文中所提到的漏洞均已提交给CNVD&CITIVD,请勿用做非法用途。

C20220511的博客 1904

51-14 Retentive Network,RetNet 多尺度保留机制序列建模论文精读

RetNet 提出了多尺度保留机制序列建模,该机制支持三种计算范式,即并行、循环和分块循环。RetNet有更好的全局注意力建模、高效的计算效率、对遮挡的鲁棒性、支持基于注意力的图像生成、与置信度相关的门控机制和多任务学习等特点,对不同视觉任务可以共享历史注意力记忆,可以同时进行分类、分割、检测等任务。RetNet在视觉领域应该有广阔的应用前景。

AIgraphX 1613

堆优化Dijkstra()算法+spfa算法(模板)

题目链接 题意: T组样例 n个顶点,m条单向边 m行 ui,vi,wi. 求源点1到其它点来回最短路 最后输出所有来回最短路相加之和 0<n≤20000,m≤60000,1≤T≤10,0≤ci​≤10^9,1≤ui​,vi,wi​≤n 题解: 单源最短路,且边权值为正数,n数据太大,邻接表存图。 解法1:spfa算法 解法2:堆优化Dijkstra()算法 如何实现堆优化: 不同结构体,用pair容器,pair可以放两个元素,相当于一个结构体,然后优先队列自动从小到大排序,排序先按pair中第一

Helinshan的博客 1525

【Linux】Windows11 安装 WSL2 并运行 Ubuntu 22.04 详细操作步骤

Windows 11 安装 WSL2 和 Ubuntu 22.04 指南 本文详细介绍在 Windows 11 上安装 WSL2 和 Ubuntu 22.04 的完整步骤,包括: WSL2 与 VirtualBox 的性能对比优势 系统版本检查与升级方法 两种安装方式(一键安装和手动安装) Ubuntu 22.04 的安装与配置 存储位置管理及迁移技巧 常用 WSL2 命令速查表 文章还提供了性能优化建议和常见问题解决方案,适合开发者和 Linux 爱好者快速搭建高效的开发环境。

No8g攻城狮的博客 2万+

优先队列优化迪杰斯特拉算法:高效求解图的最短路径

本文深入解析了如何利用优先队列优化经典的迪杰斯特拉算法,以高效求解图的最短路径问题。通过对比传统O(V²)与优化后O(E log V)的时间复杂度,并结合代码实例与性能测试,阐述了该优化如何大幅提升算法效率,适用于大规模图数据计算,是导航、网络分析等场景的核心技术。

weixin_29196613的博客 180

Qwen大模型参数解析

Qwen系列模型的参数主要分为(决定模型结构)和(控制生成行为)两类。由于该系列已迭代多个版本,参数设计也在不断演进,我会结合最新版本为你进行分层梳理。

yeyiboy的博客 165

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Dijkstra单元最短路径,最小堆优化,SPFA算法求单源最短(c++)

介绍原理的有很多,所以直接附上代码: 输入 输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。 以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。 输出 只有一行,共...

weixin_41499217的博客 451

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SWUST power oj 2862(最短路问题,优先队列优化dij)

SWUST power oj 2862 ∙\bullet∙Description 小Y在星际旅行的过程中,意外的发现了一个神奇的圆形空间,当他的飞船进入这个空间之后,他可以在这个圆形的区域内任意飞行而不需要消耗能量。而当他的飞船不在这个圆形区域内时,消耗的能量与行驶的距离在数值上相等。在小Y的旅行途中,一共有 n个这样神奇的空间。小Y想知道,他从第s个圆上某个点出发,到达第t个圆上某个点需要的最小...

spicychicken的博客 1338

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Dijkstra算法与其最小堆优化

(仿佛回到了当年打比赛的时候呢 POJ 3013(Big Christmas Tree) 传送门:http://poj.org/problem?id=3013 题目大意:由一堆顶点和边构造出一棵圣诞树,1号顶点固定为树根,顶点和边各自有权重值(均为正数)。构造圣诞树的边的开销是边权乘以子树中所有顶点的权重之和,总开销则是所有边的开销之和。求圣诞树的最小开销。 稍微变换...

LittleMagic's Blog 2629

图论(迪杰斯特拉,Floyd,bellman,spfa)

对图论和搜索的学习感想 Dijkstra 迪杰斯特拉求最短路的暴力的思路是三重循环去更新所有点到起点的最短距离。 首先先初始化让第一个点到自己的距离是0即: dist[1]=0; 然后在省下的点中找到距离起点最近的点(该点必须是没有被确定的点),然后再用该点到起点的距离更新所有点到起点的最短距离,每次更新一个最短,最短更新全部,所以第一重循环循环n次,从而达到寻找最短路的效果。 for(int i=0;i<n;i++) { //找出距离原点最短的点 .

qq_51683978的博客 2377

(更新完善版)堆优化dijkstra与spfa算法解决无负权回路单源最短路问题

启动: 2022.2.16总结 系统学习最短路算法之无负权回路单源最短路算法: 有负权回路(有回路,且回路长度总和为负数(回路之间各个点之间边的和是一个负数,那么回路转下去为负无穷))最短路不一定存在: 总体来说解决无负权回路单源最短路算法常用基础算法有1.dijkstra()2.spfa()两种算法 其中dijkstra使用堆优化版本 spfa是贝尔曼福特算法队列优化的结果 接下来来搞这俩算法! 堆优化版本dijkstra()–>java语言版 时间复杂度O(mlogn) (n是点个数

qq_51070408的博客 728

迪杰斯特拉算法避坑指南:为什么传统实现会WA而优先队列不会?

本文深入探讨迪杰斯特拉算法在传统实现与优先队列优化版本中的关键差异,揭示为什么传统方法在某些情况下会得到错误结果(WA)。通过分析最短路径算法的核心思想、时间复杂度对比以及优先队列的延迟处理机制,帮助开发者理解如何避免常见实现陷阱,并针对不同图结构选择最优解决方案。

weixin_29275257的博客 139

最短路模版(优先队列优化,迪杰斯特拉)与spfa

//都可解决有向图,无向图 优先队列优化迪杰斯特拉..(权值非负) const int maxn=...; //maxn 为最多的城市(或其他)数量 int n,m; //n个城市, m条路径 int d[maxn]; //d[i] 表示 某个城市到城市 i 的最短距离 vector<pair<int,int&...

Error Man 的博客 499

迪杰斯特拉算法C语言实现:从贪心原理到堆优化与路径回溯

图论中的最短路径问题是计算机科学和工程实践中的基础算法挑战,其核心在于如何在带权图中高效找到两点间的最优连接。迪杰斯特拉算法基于贪心策略,通过不断松弛边权来逼近全局最优解,其技术价值在于为网络路由、地图导航和资源调度等场景提供了可靠的最优路径计算框架。在工程实现中,常使用邻接矩阵或邻接表存储图结构,并借助最小堆(优先队列)将时间复杂度优化至O((V+E)log V),从而处理大规模图数据。本文以力扣1976题为具体应用场景,深入解析了C语言中迪杰斯特拉算法的实现细节,包括堆优化、路径回溯以及处理最短路径计数

weixin_34378969的博客 383

Dijkstra?spfa?SPstra?

考试或者比赛时,题目的数据我们无从得知。但我们知道的是,造数据的人们都是阴险狡诈忠恳善良的,我们可以猜疑相信他们。

STY_fish_2012的博客 1088

关于SPFA——他复活了? || 最短路算法 SPFA + 堆 = Dijkstra?

网上讲解又多又好 模板的话也不错(虽然没我的好但我现在SPFA都不打裸的了) 这里就提供一种思路 SPFA + 堆优化 跑的快快哒 不过感觉全世界的毒瘤出题人都还会想方设法地卡SPFA 具体原因 百度 "卡SPFA" 然后随便进去就行了 的确嘛 这算法都不正经= = 然后dalao们都是改用优先队列存点的 但是死不用 STL 的 Frocean...... 于是这里采用堆存储(堆和优先队...

拾月冰海的小书屋 4018
上一篇: PAT1034 Head of a Gang
下一篇: 跨站脚本攻击(XSS)初探(一)
Tate_Brown
博客等级 码龄9年 39粉丝 107原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值