【算法】Floyd多源最短路径算法

目录

一、概念

二、思路

三、代码


一、概念

在前面的学习中,我们已经接触了Dijkstra、Bellman-Ford等单源最短路径算法。但首先我们要知道何为单源最短路径,何为多源最短路径

  • 单源最短路径:从图中选取一点,求这个点到图中其他节点的最短路径
  • 多源最短路径:从图中任选两个节点,我们都能知道这两点间的最短路径

Floyd多源最短路径算法可用于求图中任意两点间的最短路径长,其核心思路在于依次将每个节点作为路径的中间点来更新其他任意两点的较优解,最后得到全局最优解


二、思路

1.首先我们需要一个图,和二维数组g、path

其中:

  • g用于存储从i到j的最短路径长度
  • path用于存储从i到j的最短路径的终点 的 前继节点

例如初始时,从1到2的最短路径就是权重为6的边,其终点为2,而对于这条路径而言2的前继节点为1,因此path[1][2] = 1

g(0)和path(0)意为矩阵g和path的初始态。因为初始时两个节点之间的最短路径就是他们之间的边,因此我们在初始化这两个数组时,只需要按照样例输入的边填写矩阵g即可

若从i到j之间没有边,则填最大值即可,例如g[3][2] = MAX,因为没有从3指向2的边

而矩阵path在初始化时按照上面的规则初始化即可,例如初始从3到1的最短路径就是3->1,终点为1,前继节点为3,因此path[3][1] = 3

2. 从1号节点开始,将每个节点作为任意两个节点的最短路径的中间点

有的人听到这里可能已经懵了,我们跟着图慢慢走

此时g(0)、path(0)变为g(1)和path(1),代表接下来要更新 i->1->j 的最短路径

但是我们并不需要将矩阵g和矩阵path中的所有值都更新,例如g[1][2],判断1->1->2的路径是否比1->2的最短路径更短是不具有价值的。两个矩阵中,如果行标和中间节点一样、列标和中间节点一样或者行标和列标一样的话,我们直接跳过即可

因此,只有2->1->3的情况,和3->1->2的情况需要讨论

(带背景色的位置代表不需要判断)

可以看到,2->1->3的距离为2->1的最短距离加1->3的最短距离,即g[2][1]+g[1][3] = 23,这个距离并不比g[2][3]小,因此不需要更新

而3->1->2的距离为11,小于原来的值MAX,因此更新,同时path[3][2]也更新为3->1->2的终点的前继节点即1

3.重复第二步直到所有节点都已作为中间点

1->2->3的距离为g[1][2]+g[2][3] = 10,比原来的13更小,因此将g[1][3]更新,path[1][3] = 2

3->2->1的距离为g[3][2]+g[2][1] = 21,比g[3][1]大,不更新

1->3->2的距离为21,比g[1][2]大,不更新

2->3->1的距离为g[2][3]+g[3][1] = 9,比原来的10更小,因此将g[2][1]更新,path[2][1] = 3

至此,我们就得到了图中任意两点间的最短路径长度了

而最短路径本身,则可以根据矩阵path中的值推出来,例如要求从2到1的最短路径,首先知道终点为节点1,根据path[2][1]知道下一个节点3,再根据path[2][3]知道下一个节点2,最后path[2][2]为-1说明路径走到结尾,因此完整的最短路径就为2->3->1


三、代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define debug(x) cout << #x << " = " << x << '\n'
#define INF 0x3f3f3f3f
using namespace std;

#define N 210
#define M 20010

int n, m, k;
int g[N][N]; //存储从i到j的最短路径长度
int path[N][N]; //path[i][j]存储从i到j最短路径的终点 的 前继节点

void Floyd()
{
    for(int i = 1; i <= n; i++)
	{
	    g[i][i] = 0; //自己到自己的路径长度设置为0
	}
	
	for(int k = 1; k <= n; k++) //代表从i经过k到j的最短路径
	{
		for (int i = 1; i <= n; i++) //第i行
		{
			for (int j = 1; j <= n; j++) //第j列
			{
				if(i == j || i == k || j == k) //多余情况
					continue;

				if(g[i][k] + g[k][j] < g[i][j]) //从i经过k到j的最短路径 比 原先从i到j的最短路径更短
				{
					g[i][j] = g[i][k] + g[k][j]; //更新从i到j的最短路径
					path[i][j] = path[k][j]; //更新从i到j最短路径的终点 的 前继节点
				}
			}
		}
	}
}

void solve()
{
	//初始化矩阵g和path
    memset(g, 0x3f, sizeof g); 
	memset(path, -1, sizeof path);

	cin >> n >> m >> k;
	for(int i = 0;i < m; i++)
	{
	    int a, b, w;
	    cin >> a >> b >> w;
	    g[a][b] = min(g[a][b], w); //可能存在重边
		path[a][b] = a; //初始时从a到b最短路径终点的前继节点就是a本身
	}

	Floyd(); //Floyd算法

	for (int i = 0; i < k; i++)
	{
		int a, b;
		cin >> a >> b;
		if(g[a][b] > INF / 2)
			cout << "impossible" << endl;
		else
			cout << g[a][b] << endl;
	}
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    //cin >> t;
    while(t--)
        solve();
    return 0;
}

完.

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

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

相关文章

【商用存储】希捷磁盘阵列部署实践

文章目录 一、前言1、盘阵类型2、性能规格 二、功能说明1、RAID配置1.1、虚拟池&#xff08;virtual pool&#xff09;1.2、线性池&#xff08;linear pool&#xff09; 2、磁盘休眠2.1、RBOD2.1.1、功能说明2.1.2、规格限制 3、ADAPT配置3.1、说明3.2、规格限制3.3、配置建议3…

Android Room框架使用指南

Room框架使用指南 项目效果创建应用,配置Gradle1、在app Module的build.gradle配置kapt插件2、配置依赖:3、配置依赖包版本号创建实体类创建DAO1、DAO简介2、WordDao设计以及相关注解说明3、监听数据变化添加Room数据库1、Room数据库简介2、实现Room数据库实现存储库实现View…

Read excerpt(eighteen)——The hidden value of Corporate Social Responsibility

“There is one and only one social responsibility of businesses,” wrote Milton Friedman, a Nobel prize-winning economist, “That is, to use its resources and engage in activities …

纯血鸿蒙系统 HarmonyOS NEXT自动化测试实践

1、测试框架选择 hdc&#xff1a;类似 android 系统的 adb 命令&#xff0c;提供设备信息查询&#xff0c;包管理&#xff0c;调试相关的命令ohos.UiTest&#xff1a;鸿蒙 sdk 的一部分&#xff0c;类似 android sdk 里的uiautomator&#xff0c;基于 Accessibility 服务&…

基于java宠物医院管理系统的设计与实现

一、环境信息 开发语言&#xff1a;JAVA JDK版本&#xff1a;JDK8及以上 数据库&#xff1a;MySql5.6及以上 Maven版本&#xff1a;任意版本 操作系统&#xff1a;Windows、macOS 开发工具&#xff1a;Idea、Eclipse、MyEclipse 开发框架&#xff1a;SpringbootHtmljQueryMysql…

施工企业为什么要用工程项目管理软件?工程项目管理软件的用处是什么?

施工企业一定会遇到哪些问题&#xff1f;工人怠工、材料浪费、数据造假、工期拖延、质量问题、安全隐患等。这些问题正在悄然侵蚀建施工业的经济效益。每一个环节的失控都可能导致巨大的经济损失&#xff0c;还可能损害企业的声誉。面对日益复杂的工程管理环境&#xff0c;如何…

业务模块部署

一、部署前端 1.1 window部署 下载业务模块前端包。 &#xff08;此包为耐威迪公司发布&#xff0c;请联系耐威迪客服或售后获得&#xff09; 包名为&#xff1a;业务-xxxx-business &#xff08;注&#xff1a;xxxx为发布版本号&#xff09; 此文件部署位置为&#xff1a;……

【Web前端】OOP编程范式

面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称 OOP&#xff09;是一种程序设计思想&#xff0c;它通过将程序视为一组相互作用的对象来设计程序。OOP 提出了一些重要的基本概念&#xff0c;包括类与实例、继承和封装。面向对象编程将系统视为由多个对象…

C++入门基础知识142—【关于C++ 友元函数】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 友元函数的相关内容&#xff01; 关于…

BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测

BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测 目录 BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 …

vue实现图片无限滚动播放

本人vue新手菜鸡&#xff0c;文章为自己在项目中遇到问题的记录&#xff0c;如有不足还请大佬指正 文章目录 实现效果代码展示总结 因为刚接触vue&#xff0c;本想着看看能不能用一些element的组件实现图片的轮播效果&#xff0c;尝试使用过element-UI里的走马灯Carouse&#x…

python画图|灵活的subplot_mosaic()函数-初逢

【1】引言 前述学习进程中&#xff0c;对hist()函数画直方图已经有一定的探索。然而学无止境&#xff0c;在继续学习的进程中&#xff0c;我发现了一个显得函数subplot_mosaic()&#xff0c;它几乎支持我们随心所欲地排布多个子图。 经过自我探索&#xff0c;我有一些收获&am…

ODOO学习笔记(1):ODOO的SWOT分析和技术优势是什么?

ODOO是一款开源的企业管理软件套件&#xff0c;广泛应用于企业管理中。它由比利时的Odoo S.A.公司开发&#xff0c;最初名为OpenERP&#xff0c;现在已经成为全球流行的ERP解决方案之一。ODOO集成了ERP、CRM、电子商务和CMS等多种功能模块&#xff0c;适用于各种规模的企业应用…

淘酒屋殷卓荣窖主高端客户私享答谢晚宴暨意大利摩罗斯酒庄之夜

一边是热爱&#xff0c;一边是事业&#xff0c;鱼与熊掌兼得淘酒屋殷卓荣窖主答谢晚宴圆满结束 淘酒屋殷卓荣窖主高端 VIP 客户私享答谢晚宴暨意大利摩罗斯酒庄品鉴之夜在广州四季酒店 99 楼圆满举办 2024 年 11 月 8 日晚&#xff0c;一场别开生面的淘酒屋殷卓荣窖主高端 VI…

LeetCode热题100之贪心算法

1.买卖股票的最佳时机 思路分析&#xff1a;即需要找出某一天的最低价格和它后面几天的最高价格差。 维护一个变量min_price&#xff0c;表示到目前为止遇到的最低股票价格&#xff1b;遍历prices数组&#xff0c;在每一天的价格上&#xff1a; 更新min_price为当前的价格和mi…

SL6115降压恒流 60V降压恒流芯片,高精度1%,PWM模拟调光

一、核心参数与性能 工作电压范围&#xff1a;5.5V至60V&#xff0c;宽输入电压范围使其能够适应多种应用场景。 最大输出电流&#xff1a;根据公开发布的信息&#xff0c;SL6115的最大输出电流可达到1.2A至1.5A&#xff0c;具体取决于不同版本或制造商的规格说明。这一高输出…

测试概念以及测试bug

关于测试的概念 什么是需求&#xff1f; 需求分为用户需求和软件需求。 软件需求可以作为开发和测试工作的依据&#xff0c;而用户需求不一定是合理的&#xff0c;这里的不合理有很多的角度&#xff1a;技术角度上&#xff0c;市场需求上&#xff0c;投入成本和收益比噔噔。…

【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者

在工业领域&#xff0c;工业风扇的稳定高效运行对于维持良好的生产环境至关重要。而驱动芯片作为工业风扇控制系统的核心元件&#xff0c;其性能直接影响风扇的工作状态。芯麦 GC5931 作为一款新型驱动芯片&#xff0c;在替代 A5931/Allegro 应用于工业风扇中展现出了非凡的优势…

阿里云docker安装禅道记录

docker network ls docker network create -d bridge cl_network sudo docker run --name zentao --restart always -p 9982:80 --networkcl_network -v /data/zentao:/data -e MYSQL_INTERNALtrue -d hub.zentao.net/app/zentao:18.5 升级禅道 推荐用按照此文档升级&a…

艾体宝产品丨加速开发!Redis Copilot智能助手上线

我们最近发布了 Redis Copilot&#xff0c;旨在帮助开发者更加高效地使用 Redis 构建应用。提升应用性能&#xff0c;简化构建过程是我们不懈的追求。Redis Copilot 正是为此而生的人工智能助手&#xff0c;助力开发者迅速掌握 Redis 的使用技巧。现在您可以在 Redis Insight 中…