图的最短路径

news2024/12/22 20:03:42

文章目录

    • 单源最短路径-Dijkstra算法
    • 单源最短路径--Bellman-Ford算法
    • 多源最短路径--Floyd-Warshall算法

单源最短路径-Dijkstra算法

针对一个带权有向图G,将所有结点分为两组S和Q,S是已经确定最短路径的结点集合,在初始时为空(初始时就可以将源节点s放入,毕竟源节点到自己的代价是0),Q 为其余未确定最短路径的结点集合,每次从Q 中找出一个起点到该结点代价最小的结点u ,将u 从Q 中移出,并放入S 中,对u 的每一个相邻结点v 进行松弛操作。松弛即对每一个相邻结点v ,判断源节点s到结点u 的代价与u 到v 的代价之和是否比原来s 到v 的代价更小,若代价比原来小则要将s 到v 的代价更新为s 到u 与u 到v 的代价之和,否则维持原样。如此一直循环直至集合Q 为空,即所有节点都已经查找过一遍并确定了最短路径,至于一些起点到达不了的结点在算法循环后其代价仍为初始设定的值,不发生变化。
在这里插入图片描述
在这里插入图片描述

void Dijkstra(const V& src, vector<W>& dist, vector<int>& parentPath)
{
	int n = _vertexs.size();
	dist.resize(n,MAX_W);
	parentPath.resize(n, MAX_W);
	int srci = findIndex(src);
	
	parentPath[srci] = srci;
	dist[srci] = 0;
	vector<bool> minPath(n, false);
	
	for (int i = 0; i < n; i++)
	{
		// 找到最小的节点
		int mini = 0;
		int minW = MAX_W;
		for (int j = 0; j < n; j++)
		{
			if (minPath[j] == false && dist[j] < minW)
			{
				minW = dist[j];
				mini = j;
			}
		}

		minPath[mini] = true;
		//从最小的节点延伸出去
		for (int j = 0; j < n; j++)
		{
			// 从该节点延伸出去比员节点小
			if (_matrix[mini][j] != MAX_W && 
			dist[mini] + _matrix[mini][j] < dist[j])
			{
				dist[j] = dist[mini] + _matrix[mini][j];
				parentPath[j] = mini;
			}
		}
	}
}

缺点:Dijkstra算法无法解决带负权值的图

单源最短路径–Bellman-Ford算法

设i是src的一个中间节点,那么从src到j的最短路径p就被分成src到i和i到j的两段最短路径p1,p2。p1是从src到i且中间节点取得的一条最短路径。p2是从i到j且中间节点属于取得的一条最短路径。
i可以为src外的任意节点,因此进行k此后可以保证所得的结果是最小路径

bool BellmanFord(const V& src, vector<W>& dist, vector<int>& parentPath)
{
	int n = _vertexs.size();
	dist.resize(n, MAX_W);
	parentPath.resize(n, MAX_W);
	int srci = findIndex(src);

	parentPath[srci] = srci;
	dist[srci] = 0;
	vector<bool> minPath(n, false);

	for (int k = 0; k < n; k++)
	{
		bool exchange = false;
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				// // srci->i + i->j < srci->j 则更新路径及权值 
				if (dist[i] != MAX_W && _matrix[i][j] != MAX_W && 
				dist[i] + _matrix[i][j] < dist[j])
				{
					dist[j] = dist[i] + _matrix[i][j];
					parentPath[j] = i;
					exchange = true;
				}
			}
		}
		if (exchange == false)
			break;
	}
	return true;
}

多源最短路径–Floyd-Warshall算法

与Bellman-Ford算法的大体思路类似-从单个节点改为了多个节点
设k是p的一个中间节点,那么从i到j的最短路径p就被分成i到k和k到j的两段最短路径p1,p2。p1是从i到k且中间节点属于{1,2,…,k-1}取得的一条最短路径。p2是从k到j且中间节点属于{1,2,…,k-1}取得的一条最短路径。

void FloydWarShall(vector<vector<W>>& vvDist, vector<vector<int>>& vvParentPath)
{
	int n = _vertexs.size();

	vvDist.resize(n, vector<W>(n, MAX_W));
	vvParentPath.resize(n, vector<int>(n, -1));


	for (int i = 0; i < n; i++)
	{
		vvDist[i][i] = W();
		vvParentPath[i][i] = i;
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			//i->j
			if (_matrix[i][j] != MAX_W)
			{
				vvDist[i][j] = _matrix[i][j];
				vvParentPath[i][j] = i;
			}
		}
	}

	for (int k = 0; k < n; k++)
	{
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{

				//i->k + k->j < i->j 则更新路径及权值 
				if (vvDist[i][k] != MAX_W && vvDist[k][j] != MAX_W
					&& vvDist[i][k] + vvDist[k][j] < vvDist[i][j])
				{
					vvDist[i][j] = vvDist[i][k] + vvDist[k][j];
					vvParentPath[i][j] = vvParentPath[k][j];
				}
			}
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用监控诊断工具Arthas(阿尔萨斯)

Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类加载信…

【python】实现精美圣诞树-拿下女神不是梦

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

Java Web基础面试题

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java面试题…

【K3s】第4篇 一篇文章带你了解使用Kompose

目录 1、Kompose介绍 2、安装Kompose 3、docker-compose文件转换为k8s文件 1、Kompose介绍 kompose是一个帮助熟悉 Kubernetes 的用户迁移到k8s的工具。 获取 Docker Compose 文件并将其转换为 Kubernetes 资源。 kompose是一个方便的工具&#xff0c;可以从本地 Docker …

Ffuf爆破神器(超详细)

目录为什么是Ffuf基本使用最基本的使用多个字典同时使用带cookie扫描&#xff08;-b&#xff09;静默模式&#xff08;-s&#xff09;递归扫描&#xff08;-recursion&#xff09;指定扩展名&#xff08;-e&#xff09;POST请求爆破方式1&#xff1a;指明请求地址和请求体【不推…

iOS 自动化测试踩坑(一): 技术方案、环境配置与落地实践

移动端的自动化测试&#xff0c;最常见的是 Android 自动化测试&#xff0c;我个人觉得 Android 的测试优先级会更高&#xff0c;也更开放&#xff0c;更容易测试&#xff1b;而 iOS 相较于 Android 要安全稳定的多&#xff0c;但也是一个必须测试的方向&#xff0c;这个系列文…

Android实现雪花特效自定义view

一、前言 这个冬天&#xff0c;老家一直没有下雨&#xff0c; 正好圣诞节&#xff0c;就想着制作一个下雪的特效。 圣诞祝福&#xff1a;平安夜&#xff0c;舞翩阡。雪花飘&#xff0c;飞满天。心与心&#xff0c;永相伴。 圣诞节是传统的宗教节日&#xff0c;对于基 督徒&…

前端自学你还在浪费时间吗?

其实最主要不是学的过程&#xff0c;而是学完后&#xff0c;你有没有把今天的练习题自己在重新敲个2&#xff0c;3遍&#xff0c;这样印象就会更加深刻&#xff0c;以后自己写代码的时候也会更加的得心应手。 手抄笔记让我打好了HTML基础和良好的CSS能力&#xff0c;当然这不一…

Cesium打包入门(gulp与esbuild)

本文针对Cesium源码包的打包工具gulp和esbuild进行了初步探讨&#xff0c;属于入门篇。 首先简要介绍采用gulpesbuild如何为多个源代码文件打包成一个单独文件&#xff0c;然后介绍了下Cesium中的源码包的结构&#xff0c;并简要分析了其打包的相关函数。 本文编译环境IDE使用…

【并发编程学习】一、线程的基本认识

一、线程的基本认识 1.1线程的基本介绍 线程是什么&#xff1f; 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运行单位。 为什么会有多线程&#xff1f; ①因为其是CPU的最小调度单位&#xff0c;所以在多核CPU中&#xff0c…

圣诞节,深圳街头有点冷清了~

正文大家好&#xff0c;我是bug菌~今天是圣诞节&#xff0c;这也是我新冠康复的第二周了吧&#xff0c;还有点小咳嗽&#xff0c;伴随有点鼻炎&#xff0c;不过这周已经上了三天班了&#xff0c;整体感觉还算好吧&#xff0c;毕竟我嘴巴不硬&#xff0c;也比较低调不嚣张&#…

底层硬件创新夯实算力、应用创新贴近业务:英特尔至强助力下的VR医疗培训系统

早在1935年&#xff0c;科幻小说家斯坦利温鲍姆的小说《皮格马利翁的眼镜》中&#xff0c;就构想了一款实现虚拟现实&#xff08;VR&#xff09;的眼镜。近年来&#xff0c;除游戏、娱乐等大众熟知的应用场景外&#xff0c;VR逐渐涉足医疗、教育、生产制造等各种领域。 以医疗…

LeetCode-1759-统计同构子字符串的数目

1、数学 我们可以使用数学进行分析&#xff1a;每当出现连续的nnn个字符时&#xff0c;我们最终将其合在一起进行计算个数。显然我们可以获得的同构子字符串的个数应为n(n1)2\frac{n \times (n1)}{2}2n(n1)​。因此我们只需要遍历整个字符串&#xff0c;分别统计连续出现的字符…

57岛屿数量-61全排列 最长递增路径

57岛屿数量 矩阵中多处聚集着1&#xff0c;要想统计1聚集的堆数而不重复统计&#xff0c;那我们可以考虑每次找到一堆相邻的1&#xff0c;就将其全部改成0&#xff0c;而将所有相邻的1改成0的步骤又可以使用深度优先搜索&#xff08;dfs&#xff09;&#xff1a;当我们遇到矩阵…

AtCoder Beginner Contest 283 (A~F)

比赛名称&#xff1a;UNIQUE VISION Programming Contest 2022 Winter(AtCoder Beginner Contest 283) 比赛链接&#xff1a;AtCoder Beginner Contest 283 A - Power 题意&#xff1a; 求A^B(1<A,B<9) 要注意这个int强制转换&#xff0c;不然9^9输出结果时387420489&…

python根据json数据画疫情分布地图

目录 一.基础地图使用 1.掌握使用pyecharts构建基础的全国地图可视化图表 二.疫情地图——国内疫情地图 1.案例效果 代码 三.疫情地图——省级疫情地图 四.数据集 注&#xff1a;数据集在文章最后 一.基础地图使用 1.掌握使用pyecharts构建基础的全国地图可视化图表 演…

Learning to Segment Every Thing

摘要 现有的目标实例分割方法要求所有训练样本都具有分割mask标注。然而&#xff0c;标注新的类别是非常费劲的&#xff0c;因此这将实例分割模型的应用范围限制在100个左右的有标注的类。本文的目的是提出一种新的部分监督的训练模型&#xff0c;以及一种新的权重传递函数&am…

洛谷【算法1-7】搜索刷题——优化、错题

文章目录[USACO1.5]八皇后 Checker Challenge题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思路搜索框架代码位运算优化lowbit运算思路kkksc03考前临时抱佛脚题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思路代码吃奶酪题目描述输入格式输…

C++ STL 之可变长数组 Vector 详解

文章目录Part.I AttentionChap.I 注意事项Chap.II 操作技巧Part.II FunctionChap.I 构造函数Chap.II 增加函数Chap.III 删除函数Chap.IV 遍历函数Chap.V 判断/大小/其他函数Part.III CodePart.I Attention Chap.I 注意事项 使用vector需要注意的地方&#xff1a; 加引用#inc…

分布式与微服务系列 - SpringBoot + Zookeeper集群 + Dubbo分布式托管(提供者、消费者)+ Nginx反向代理

一、前言 本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 再搭建集群项目前&#xff0c;请先学习相关技术的知识&#xff1a; 分布式与微服务系列 - Dubbo分布式与微服务系列 - Zookeeper上篇&#xff1a;入门到精通参考文档&#xff1a;分布式与微服务…