【算法】Bellman-Ford单源最短路径算法(附动图)

目录

一、性质

二、思路

三、有边路限制的最短路


一、性质

  • 适用于含有负权边的图(Dijkstra不适用)

  • 更简单,但效率慢

  • 如果对应路径存在负权回路则没有最短路径(可用于判断图中是否存在负权回路)

  • 相比于spfa,若最短路径有边数限制则只能使用Bellman-Ford

负权回路:图中带环且环中所有边的权重和为负


二、思路

Bellman-Ford算法的思路十分简单粗暴

与Dijkstra类似的,我们用一个dist数组存放源节点到任意节点的最短路径

首先,在求最短路径前,我们需要将源节点到自己的距离初始化为0,到其他节点的距离初始化为最大值

然后,我们遍历所有的边

对于一条边,我们这里可以直接用一个结构体存储其信息,例如:

struct edge{int a, b, w;
}edges[M];

其中a为有向边出发的节点,b为有向边指向的节点,w为边的权重

遍历所有的边,如果 dist[a]+w < dist[b] ,则更新最短路径

以同样的方式一共循环n次,我们就能得到源节点到任意节点的最短路径

 

有时不一定非要循环n次才能得到最优解,例如上面我们只循环了3次。但最坏的情况下,如果我们的图是这样的呢?

有n个节点,但只有n-1条边,我们至少循环n-1次才能将所有节点更新

那我们不能只循环n-1次吗?

前面提到,Bellman-Ford算法可用于检测图中是否存在负权回路,具体是如何检测的?靠的就是这多出来的一次循环

首先解释一下为何路径中存在负权回路则不存在最短路径,因为我们如果在这个负权回路中一直走,那么路径长度不就一直在变小直到负无穷吗?

可以看到,在上面最坏的情况下,我们也只需要循环n-1次就能将源节点到每个节点的最短路径求出来,而最后一次循环中不会有节点被更新。但如果存在负权回路,则最后一次循环中一定还会有节点被更新。通过判断我们就可以知道图中是否存在负权回路。

即使每次遍历边的顺序不同也不会影响最后的结果,但每次循环中dist数组中的值可能不同。因为如果遍历边的顺序与边的指向一致,我们可以连续更新多个节点,例如:

可以看到dist的数组更新是串联的,即一个位置更新可能影响到其他位置,如果我们没有对最短路径的边数进行限制的话就无需多虑,但如果最短路径有边数限制,那我们就需要一个额外的备份数组来辅助节点更新


三、有边路限制的最短路

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 510, M = 10010;struct edge{int a, b, w;
}edges[M];int n, m, k;
int dist[N], backup[N]; 
//最短路径有边数限制,所以我们还需要一个备份数组int bellman_ford()
{//初始化dist数组memset(dist, 0x3f, sizeof dist); dist[1] = 0; //最短路径不能超过k条边,因此我们循环k次for(int i = 0;i < k;i++) {//将上一次循环中dist数组的结果存入backup数组memcpy(backup, dist, sizeof dist); for(int j = 0;j < m;j++){int a, b, w;a = edges[j].a, b = edges[j].b, w = edges[j].w;dist[b] = min(dist[b], backup[a] + w); //用backup数组来更新dist数组}}return dist[n];
}int main()
{cin >> n >> m >> k;for(int i = 0;i < m;i++){int a, b, w;cin >> a >> b >> w;edges[i] = {a,b,w}; //存边}int ans = bellman_ford(); //Bellman-Ford算法if(ans > 0x3f3f3f3f / 2) cout << "impossible"; //返回值过大不符合预期,可以判断不存在满足条件的路径else cout << ans;return 0;
}

如有错误,欢迎在评论区指出

完.

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

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

相关文章

[分享] SQL在线编辑工具(好用)

在线SQL编写工具&#xff08;无广告&#xff09; - 在线SQL编写工具 - Web SQL - SQL在线编辑格式化 - WGCLOUD

物联网实训项目:绿色家居套件

1、基本介绍 绿色家居通过物联网技术将家中的各种设备连接到一起&#xff0c;提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。绿色家居提供全方位的信息交互功能&#xff0c;甚至为各种能源费…

solana phantom NFT图片显示不出来?

solana phantom NFT图片显示不出来&#xff1f; 问题 同样是jpeg格式图片&#xff0c;一个phatom可以显示&#xff0c;一个不可以显示为什么&#xff0c;nft图片格式大小有要求吗&#xff1f; 问题分析 Phantom 官网有一些关于 NFT 集成的文档,其中可能会有关于图片大小限制…

049_python基于Python的热门微博数据可视化分析

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

15分钟学Go 第7天:控制结构 - 条件语句

第7天&#xff1a;控制结构 - 条件语句 在Go语言中&#xff0c;控制结构是程序逻辑的重要组成部分。通过条件语句&#xff0c;我们可以根据不同的条件采取不同的行动。今天我们将详细探讨Go语言中的两种主要条件结构&#xff1a;if语句和switch语句。理解这些控制结构对于编写…

CTA-GAN:基于生成对抗网络对颈动脉和主动脉的非增强CT影像进行血管增强

写在前面 目前只分析了文章的大体内容和我个人认为的比较重要的细节&#xff0c;代码实现还没仔细看&#xff0c;后续有时间会补充代码细节部分。 文章地址&#xff1a;Generative Adversarial Network-based Noncontrast CT Angiography for Aorta and Carotid Arteries 代…

JAVA基础面试题准备

一些常见的JAVA基础题&#xff0c;面试中遇到过的会加*显示。 JAVA基础 1.Java中重载和重写的区别&#xff1f;* 2.int 和Integer类型这两个区别吗&#xff1f; 为什么需要有Integer类型&#xff1a; int和Integer类型的区别&#xff1a; 3.遍历list有那些方式吗&#xff1f;…

【Linux】进程信号(下)

目录 一、信号的阻塞 1.1 信号在内核中的保存方式 1.2 sigset_t信号集 &#xff08;1&#xff09;信号集操作 &#xff08;2&#xff09;sigprocmask函数 &#xff08;3&#xff09;sigpending函数 二、信号的处理 2.1 用户态和内核态 2.2 重谈进程地址空间 三、信号…

盘点2024年4款高清稳定的Windows10录屏工具。

Windows10电脑录屏在生活当中还是挺重要的&#xff0c;无论是教育领域的制作教程&#xff0c;还是游戏玩家记录精彩瞬间&#xff0c;亦或是商务人士进行演示&#xff0c;录屏都能发挥巨大作用。如果设备自带的一些工具无法完成录屏需求的话&#xff0c;这里帮大家找了几款好用到…

AI大模型应用(3)开源框架Vanna: 利用RAG方法做Text2SQL任务

AI大模型应用(3)开源框架Vanna: 利用RAG方法做Text2SQL任务 RAG&#xff08;Retrieval-Augmented Generation&#xff0c;如下图所示&#xff09;检索增强生成&#xff0c;即大模型LLM在回答问题时&#xff0c;会先从大量的文档中检索出相关信息&#xff0c;然后基于这些检索出…

万家数科:零售业务信息化融合的探索|OceanBase案例

本文作者&#xff1a;马琳&#xff0c;万家数科数据库专家。 万家数科商业数据有限公司&#xff0c;作为华润万家旗下的信息技术企业&#xff0c;专注于零售行业&#xff0c;在为华润万家提供服务的同时&#xff0c;也积极面向市场&#xff0c;为零售商及其生态系统提供全面的核…

挖矿病毒来势汹汹

病毒来了, 我的个人站点使用了 wordpress, 它的不知哪个漏洞让黑客攻入了我的站点 使用 top 命令看到了有不明进程始终占据了 100% 的 CPU snapshot 1 snapshot 2 通过以下 "三板斧"可以查杀这个进程 先用 top (shiftp) 查找占据 CPU 最多的进程根据其进程号 pid 查看…

【数据结构】宜宾大学-计院-实验四

栈和队列之&#xff08;栈的基本操作&#xff09; 实验目的&#xff1a;实验内容&#xff1a;实验结果&#xff1a;实验报告:&#xff08;及时撰写实验报告&#xff09;&#xff1a;实验测试结果&#xff1a;代码实现1.0&#xff1a;&#xff08;C/C&#xff09;【含注释】代码…

QGIS之三十二DEM地形导出三维模型gltf

效果 1、准备数据 (1)dem.tif (2)dom.tif 2、qgis加载dem和dom数据 3、安装插件 插件步骤可以参考这篇文章 QGIS之二十四安装插件 安装了Qgis2threejs插件,结果

无人机之自主降落系统篇

一、定义与功能 无人机自主降落系统是指无人机在无需人工干预的情况下&#xff0c;按照预先设定好的程序或基于实时感知的环境信息&#xff0c;自主完成降落过程的技术系统。该系统能够确保无人机在完成任务后安全、准确地降落到指定位置。 二、系统组成 无人机自主降落系统主…

ELK之路第二步——可视化界面Kibana

Kibana 1.安装2.解压3.修改配置4.启动 这部分内容就比较简单了&#xff0c;水一片文章。 1.安装 需要梯子 官网下载链接&#xff1a;https://www.elastic.co/cn/downloads/past-releases/kibana-7-3-0 如果你去官网下载页面&#xff0c;点击下载是404报错&#xff0c;记得切换…

redis的zset实现下滑滚动分页查询思路

常规zset查询 我们redis的数据为 我们知道 我们常规查询的话 我们假如 zset 表中 有7个元素&#xff0c;然后我们进行分页查询的话&#xff0c;我们一次查3个元素&#xff0c;然后查出来元素 和元素的分数 我们redis的语法应该这样写 zrevrangebyscore wang 1000 0 withsc…

Flutter 12 实现双击屏幕显示点赞爱心多种动画(AnimationIcon)效果

本文主要是使用Flutter封装一个双击屏幕显示点赞爱心UI效果&#xff0c;并实现了爱心Icon 透明度、缩放、旋转、渐变等动画效果。 实现效果&#xff1a; 实现逻辑&#xff1a; 1、封装FavoriteGesture&#xff08;爱心手势&#xff09;实现双击屏幕显示爱心Icon&#xff1b; …

【设计模式系列】抽象工厂模式

一、什么是抽象工厂模式 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一个接口&#xff0c;用于创建一系列相关或相互依赖的对象&#xff0c;而无需指定它们具体的类。这种模式允许客户端使用抽象的接口来创建一组…

VoLTE 微案例:VoLTE 注册失败,I-CSCF 返回 403,HSS(UAR) 返回 5001

目录 1. 问题描述 2. 故障注册流程与正常流程对照 3. 结论 博主wx:yuanlai45_csdn 博主qq:2777137742 想要 深入学习 5GC IMS 等通信知识(加入 51学通信),或者想要 cpp 方向修改简历,模拟面试,学习指导都可以添加博主低价指导哈。 1. 问题描述