(算法基础)Bellman-ford算法

news/2023/11/28 6:01:20

适用情景

  1. Bellman-ford算法一般运用在求最短路的问题当中,适用于求最短路问题的单源最短路的存在负权边的情况。


时间复杂度

  1. 时间复杂度为O(m*n),n表示有n个点,m表示有m条边。


算法解释

  1. 首先是循环(迭代)n次,当然实际情况也不一定要求是n次,也可以是k次。但是这里面的实际意义非常关键:如果说该算法循环k-1次,从1号点经过k-1条边能够到达的所有点你们的最短距离已经确定下来;如果说该算法循环k次,从1号点经过k条边能够到达的所有点你们的最短距离也已经确定下来........ (当然,这个最短距离并不是最优版,是在只经过<=k条边的情况下的最短距离)

  1. 在每一次循环里面,去遍历所有的边(也正是因为如此,所以说这个算法里面存边的方式可以很随意,因为我只需要保证所有的边都能够全部遍历到就可以,因此可以直接开一个结构体去存边就行)。

struct point    //存边(a,b,c)  表示从点a指向点b,权重为c
{int x;int y;int z;
}
  1. 接上文,比如说对于每一条边a,b,c(表示从点a指向点b,权重为c),那么这时候就干这个操作:

dist[b]=min(dist[b],dist[a]+c)   //先不考虑备份,大意先搞懂
  1. 在刚开始创建dist数组的时候,默认所有的点到一号点的距离都是无穷大,当然一号点本身除外。

memset(dist,0x3f,sizeof(dist));
dist[1]=0;
  1. 在进行每一次循环迭代的时候。需要进行一个备份操作,把dist数组先备份到backup数组里面,这主要是为了防止串联现象的发生。如图解:

没有开始循环的时候,dist[ 1 ]=0, dist [ 2 ]与dist[ 3 ]都是正无穷大。然后进行了一次循环/迭代,这时候由于2号点与3号点都是可以通过1号点只经过一条边就可以走到,因此二号点和三号点的最短路已经确定,它们的最短距离分别为1和3。然后我们根据这个算法,在每一次循环的时候去遍了所有的边(3条),每次都dist[ b ] = dist[ a ] + c ; 如果没有备份的话,会导致dist[ 3 ]最终变为2,虽然2确实是更加优化的最短距离,但是这个最短距离是在从1号点经过两条边的基础之上,而我现在只进行了一次循环,我所得到的是从1号点只经过1条边走到的所有点的在最短路中边数为1这个前提下的最短距离。

for (int i=0;i<k;i++)
{memcpy(backup,dist,sizeof(dist));for (int j=1;j<=m;j++){dist[b]=backup[a]+c;}
}
  1. 最后万一如果说从1号点是走不到n号点的,这种情况该如何在循环结束后去判断呢?因为dist数组所有元素初始化都是无穷大0x3f3f3f3f,但这边有个小坑,不能直接等于这个数字去判断。因为我们知道每次循环的话都会去遍历所有的边,在这个过程当中如果说n号点与某一个点之间存在着负权边,那么会对这个无穷大的数字造成略微的缩小。因此要这样子

if (dist[n]>0x3f3f3f3f/2)
{printf("impossible\n");
}
.........

例题

来源:AcWing

853. 有边数限制的最短路 - AcWing题库

#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
typedef struct point 
{int a;int b;int c;
}point;
int main()
{int n,m,k,a,b,c=0;scanf("%d %d %d",&n,&m,&k);point arr[m+1];int dist[n+1];memset(dist,0x3f,sizeof(dist));dist[1]=0;int backup[n+1];for (int i=1;i<=m;i++){scanf("%d %d %d",&a,&b,&c);arr[i].a=a;arr[i].b=b;arr[i].c=c;}for (int i=0;i<k;i++){memcpy(backup,dist,sizeof(dist));for (int j=1;j<=m;j++){dist[arr[j].b]=MIN(dist[arr[j].b],backup[arr[j].a]+arr[j].c);}}if (dist[n]>0x3f3f3f3f/2){printf("impossible\n");}else{printf("%d\n",dist[n]);}return 0;
}


http://www.ppmy.cn/news/33309.html

相关文章

C # FileStream文件流

本章讲述&#xff1a;FileStream类的基本功能&#xff0c;以及简单示例&#xff1b; 1、引用命名空间&#xff1a;using System.IO; 2、注意&#xff1a;使用IO操作文件时&#xff0c;要注意流关闭和释放问题&#xff01; 强力推荐&#xff1a;将创建文件流对象的过程写在usi…

人脸活体检测系统(Python+YOLOv5深度学习模型+清新界面)

摘要&#xff1a;人脸活体检测系统利用视觉方法检测人脸活体对象&#xff0c;区分常见虚假人脸&#xff0c;以便后续人脸识别&#xff0c;提供系统界面记录活体与虚假人脸检测结果。本文详细介绍基于YOLOv5深度学习技术的人脸活体检测系统&#xff0c;在介绍算法原理的同时&…

传输层协议之TCP协议详解

传输层重点协议&#xff1a;UDP和TCP。作用&#xff1a;负责数据能够从发送端传输到接收端。&#xff08;在进行网络编程时&#xff0c;我们会使用到socket&#xff0c;然而一旦调用socket就进入到了传输层的范畴内&#xff09;前面我们已经讲过UDP协议了&#xff0c;这次我们来…

GPT-4 API 接口调用及价格分析

GPT-4 API 接口调用及价格分析 15日凌晨&#xff0c;OpenAI发布了万众期待的GPT-4&#xff01;新模型支持多模态&#xff0c;具备强大的识图能力&#xff0c;并且推理能力和回答准确性显著提高。在各种专业和学术基准测试上的表现都媲美甚至超过人类。难怪OpenAI CEO Sam Altm…

Linux之定时任务调度

文章目录一、crond 任务调度概述快速入门特殊符号的说明特定时间执行任务案例应用实例二、at定时任务基本介绍at命令格式at时间定义at命令选项应用实例一、crond 任务调度 crontab进行定时任务的设置 概述 任务调度:是指系统在某个时间执行的特定的命令或程序。 任务调度分…

面试官:rem和vw有什么区别

"rem" 和 "vw"的区别 "rem" 和 "vw" 都是用于网页设计的CSS单位。 "rem" 是相对于根元素的字体大小来计算的单位&#xff0c;即相对于 "html" 标签的字体大小。例如&#xff0c;如果 "html" 标签的字…

【MySQL】数据库的约束

哈喽&#xff0c;大家好&#xff01;我是保护小周ღ&#xff0c;本期为大家带来的是 MySQL 数据库中对表的约束&#xff0c;主要有null (空约束)&#xff0c;unique(唯一约束)&#xff0c;primary key(主键约束)&#xff0c;default(默认值约束), forelgn key(外键约束)&#x…

AI_Papers周刊:第六期

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 2023.03.13—2023.03.19 文摘词云 Top Papers Subjects: cs.CL 1.UPRISE: Universal Prompt Retrieval for Improving Zero-Shot Evaluation 标题&#xff1a;UPRISE&#xff1a;改进零样本评估…

opencv仿射变换之获取变换矩阵

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

Linux中日志管理和常见故障

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…

计算机面试常见问答题目

英语口语 自我介绍 Hello, teachers. My name is Wang Xu. I come from Ningxia. I graduated from the School of Computer Science, Xi an Jiaotong University, majoring in Internet of Things. Next, I will introduce myself from four aspects. First of all, I studi…

python 内置函数和多线程

以下是Python的一些内置函数。这些函数是Python语言提供的基本功能&#xff0c;可以在不需要导入任何其他模块的情况下直接使用。这些函数可以完成广泛的任务&#xff0c;例如数学运算&#xff0c;序列和集合操作&#xff0c;类型转换&#xff0c;文件操作等等。透彻理解这些函…

【动态规划】最长上升子序列(单调队列、贪心优化)

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

【LeetCode】1609. 奇偶树、1122. 数组的相对排序

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 1609. 奇偶树 1609. 奇偶树 题目描述&#xff1a; 如果一棵二叉树满足下述几个条件&#x…

Linux安装EMQX(简洁版)

安装目录 mkdir /opt/emqx && cd /opt/emqx 安装包下载 yum -y install wget && wget https://www.emqx.com/zh/downloads/broker/5.0.20/emqx-5.0.20-el7-amd64.tar.gz 注意&#xff1a;https://www.emqx.com/zh/downloads/broker获取下载链接并替换(后缀&…

《Linux的权限》

本文主要对linux的一些基本权限进行讲解 文章目录前言Linux权限&#xff08;1&#xff09;权限的概念&#xff08;2&#xff09;linux下用户分类(root,普通)(3)linux的文件属性文件属性的分类文件权限修改文件权限1、chmod2、chown和chgrp3、fiile权限的三个重要的问题第一个问…

leetcode——203.移除链表元素

文章目录&#x1f428;1.题目&#x1fa85;2.解法1-头节点迭代&#x1f33f;2.1 思路&#x1f33f;2.2 代码实现&#x1f986;3. 解法2-创建新链表&#x1f38f;3.1 思路&#x1f38f;3.2 代码实现&#x1f410;4. 题目链接&#x1f428;1.题目 给你一个链表的头节点head和一个…

Three.js——learn02

Three.js——learn02Three.js——learn02通过轨道控制器查看物体OrbitControls核心代码index2.htmlindex.cssindex2.jsresult添加辅助器1.坐标轴辅助器AxesHelper核心代码完整代码2.箭头辅助器ArrowHelper核心代码完整代码3.相机视锥体辅助器CameraHelper核心代码完整代码Three…

MySQL8 双主(主主)架构部署实战

前言 大家好&#xff0c;我是 沐风晓月 本文收录于《数据库入门到精通系列》专栏&#xff0c; 更多内容可以关注我的csdn博客。 本文主要讲解MySQL主主架构实战,在开始之前需要根据下面的提示来配置环境&#xff1a; Linux基础命令不熟参考&#xff1a; 《linux基本功-基础…

Button(按钮)与ImageButton(图像按钮)

今天给大家介绍的Android基本控件中的两个按钮控件,Button普通按钮和ImageButton图像按钮; 其实ImageButton和Button的用法基本类似,至于与图片相关的则和后面ImageView相同,所以本节只对Button进行讲解,另外Button是TextView的子类,所以TextView上很多属性也可以应用到B…
最新文章