当前位置: 首页 > news >正文

Dijkstra求最短路篇一(全网最详细讲解两种方法,适合小白)(python,其他语言也适用)

前言:

Dijkstra算法博客讲解分为两篇讲解,这两篇博客对所有有难点的问题都会讲解,小白也能很好理解。看完这两篇博客后保证收获满满。

本篇博客讲解朴素Dijkstra算法,第二篇博客讲解堆优化Dijkstra算法Dijkstra求最短路篇二(全网最详细讲解两种方法,适合小白)(python,其他语言也适用),两中算法思路大体相同,但时间复杂度有所区别。

  • 朴素Dijkstra算法:时间复杂度 O ( n 2 ) O(n^2) O(n2)
  • 堆优化Dijkstra算法:时间复杂度 O ( m l o g n ) O(mlogn) O(mlogn)

两篇博客给出的题目内容一样,只有数据规模不一样。

题目:

题目链接:
849. Dijkstra求最短路 I

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为非负值。请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。

输入格式
第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1。

数据范围(两题不同处)
1 ≤ n ≤ 500 1≤n≤500 1n500,
1 ≤ m ≤ 1 0 5 1≤m≤10^5 1m105

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

Dijkstra算法介绍:

Dijkstra求最短路问题是图论的经典问题,首先介绍一下Dijkstra算法的流程图:

迪杰斯特拉算法采用的是一种贪心的策略。

求源点到其余各点的最短距离步骤如下:

  1. 用一个 dist 数组保存源点到其余各个节点的距离,dist[i] 表示源点到节点 i 的距离。初始时,dist数组的各个元素为无穷大。
    用一个状态数组 state 记录是否找到了源点到该节点的最短距离,state[i] 如果为真,则表示找到了源点到节点 i 的最短距离,state[i] 如果为假,则表示源点到节点 i 的最短距离还没有找到。初始时,state 各个元素为假。

在这里插入图片描述

  1. 源点到源点的距离为 0。即dist[1] = 0。在这里插入图片描述
  2. 遍历 dist 数组,找到一个节点,这个节点是:没有确定最短路径的节点中距离源点最近的点。假设该节点编号为 i。此时就找到了源点到该节点的最短距离,state[i] 置为 1。
    在这里插入图片描述
  3. 遍历 i 所有可以到达的节点 j,如果 dist[j] 大于 dist[i] 加上 i -> j 的距离,即 dist[j] > dist[i] + w[i][j](w[i][j] 为 i -> j 的距离) ,则更新 dist[j] = dist[i] + w[i][j]。在这里插入图片描述
  4. 重复 3 4 步骤,直到所有节点的状态都被置为 1。在这里插入图片描述
  5. 此时 dist 数组中,就保存了源点到其余各个节点的最短距离。
    在这里插入图片描述

思路:

首先对数据进行存储,图的存储有两种方式,一种是邻接表,一种是邻接矩阵。题目中的数据规模用邻接矩阵存储(本题数据规模是稠密图,更省空间)。

为什么要用邻接矩阵去存贮,而不是邻接表?

我们采用邻接矩阵还是采用邻接表来表示图,需要判断一个图是稀疏图还是稠密图。稠密图指的是边的条数|E|接近于|V|²,稀疏图是指边的条数|E|远小于于|V|²(数量级差很多)。本题是稠密图,显然稠密图用邻接矩阵存储比较节省空间,反之用邻接表存储。

这里需要注意的是,题目中指出图中可能存在重边和自环。

  • 重环是指两个点之间有多条边,每个边的距离不同。
  • 自环是指一个点存在一条连向自己的边。

所以为了解决重环和自环问题,存储过程中需要存距离的最小值

邻接矩阵存储代码如下:

n, m = map(int, input().split()) # 图的节点个数和边数
#  构建邻接矩阵 float("inf")在python中是无限大的意思
num = [[float("inf") for j in range(n + 1)] for i in range(n + 1)] 
for i in range(m):a, b, c = map(int, input().split())num[a][b] = min(num[a][b], c)

以题目实例为例,打印num数组(这里存储的是有向边,所以不是关于对角线对称的):

[[inf, inf, inf, inf], [inf, inf, 2, 4], [inf, inf, inf, 1], [inf, inf, inf, inf]]

邻接矩阵构建完成之后就要进行Dijkstra算法,这里直接给出代码,用详细代码给大家进行讲解。

代码及详细注释:

n, m = map(int, input().split()) # 图的节点个数和边数
#  构建邻接矩阵 float("inf")在python中是无限大的意思
num = [[float("inf") for j in range(n + 1)] for i in range(n + 1)] 
for i in range(m):a, b, c = map(int, input().split())num[a][b] = min(num[a][b], c)
dist = [float('inf') for _ in range(n + 1)]  # dist 数组用于记录每一个点距离第一个点的距离
dist[1] = 0 # 源点到源点的距离为置为 0
state = [False for _ in range(n + 1)]  # state 用于记录该点的最短距离是否已经确定def dijkstra():for i in range(n):  # 有n个点所以要进行n次迭代 (这里迭代多了并不影响结果,因为有state数组来记录每个点的状态)t = -1  # 该点不唯一,只要是在n个节点之外或者是最后一个节点就行(也可以是0,-1表示最后一个节点)for j in range(1, n + 1): # 循环每个点,找到最短距离的点,并把它赋值给t,(j表示各个节点)if not state[j] and dist[j] < dist[t]:  # 该点未找到最短距离,且j点到第一个点的距离小于t点到第一个点的距离t = jstate[t] = True   # 标记该点距离确定for j in range(1, n + 1):  #  # 根据该点更新其他所有点的距离dist[j] = min(dist[j], dist[t] + num[t][j])# 判断最后一个点的最短距离是否找到,如果为无穷大,则表示未找到,返回-1,否则返回最短距离dist[-1]if dist[n] == float('inf'):return -1else:return dist[-1]print(dijkstra())

代码看着稍微复杂点,但拿实例数据跟着过一遍就一目了然。

这里拿实例带大家过一遍:

  1. 首先进行迭代,给t赋值为最后一个点(点3)的索引(索引值为-1,写n也可以)。之后循环这三个点,只有点1的dist距离(0)是小于最后一个点的dist值的(无穷大),所以 state[1] = True,然后循环所有的点,更新所有点到源点(点1始终是源点)的距离,dist[2] = 2, dist[3] = 4(点1与点2和点3直接相连,直接更新当前距离即可)
  2. 然后给t重新赋值为-1(这点很关键,不然之后都是跟点1进行比较了,算不出结果)。循环所有点后发现只有点2dist距离(2)是小于最后一个点的dist距离的(4)(点1的state为True,也就是已经找到最短距离了,不参与其中),之后都是重复第一步操作,更新dist[3] = 3
  3. 再一次循环时未更新值,只是把state[3] = True 的最短距离更新了,之后就会输出结果3

下面也会对大家难以理解的问题进行讲解回答(重点!!!):

  1. t为什么要赋值为 -1

答:由于每一次都要找到还没有确定最短路距离的所有点中,距离当前的点最短的点(也就是始终为无穷大的值的点)。t = - 1是为了在st这个集合中找第一个点更新时候的方便所设定的(也可以是0,因为题目中不存在点0,但0的索引确始终存d在)。

  1. 为什么要进行n次迭代,dijkstra函数中for i in range(n):的意义是什么?

答:这里的每次迭代主要是更新state数组的最短距离是否被找到,每一次迭代都会固定一个点的最短距离。

  1. 如果是问编号a到b的最短距离该怎么改呢?

初始化时 dist[a]=0, 以及返回时return dist[b]

  1. 为什么dist要初始化为无穷,邻接矩阵的部分点用无穷表示呢?

答:首先对于邻接矩阵而言,存储的是两点之间边的距离,如果两点之间不存在边,那肯定用无穷大来表示到达不了,dist数组初始化无穷大是因为这里要求最短路径,需要初始化一个较大值,这里初始化无穷大以免出错。

总结:

朴素版dijkstra适合稠密图

思路:

集合S为已经确定最短路径的点集。

  1. 初始化距离 一号结点的距离为零,其他结点的距离设为无穷大(看具体的题)。
  2. 循环n次,每一次将集合S之外距离最短X的点加入到S中去(这里的距离最短指的是距离1号点最近。 点X的路径一定最短,基于贪心,严格证明待看)。然后用点X更新X邻接点的距离。

时间复杂度分析:

  • 寻找路径最短的点: O ( n 2 ) O(n^2) O(n2)
  • 加入集合S: O ( n ) O(n) O(n)
  • 更新距离: O ( m ) O(m) O(m)
  • 所以总的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

相关文章:

Dijkstra求最短路篇一(全网最详细讲解两种方法,适合小白)(python,其他语言也适用)

前言&#xff1a; Dijkstra算法博客讲解分为两篇讲解&#xff0c;这两篇博客对所有有难点的问题都会讲解&#xff0c;小白也能很好理解。看完这两篇博客后保证收获满满。 本篇博客讲解朴素Dijkstra算法&#xff0c;第二篇博客讲解堆优化Dijkstra算法Dijkstra求最短路篇二(全网…...

计算机组成原理06:浮点数运算

浮点数加减运算 之前我们提到过&#xff0c;浮点数具有特定的表示形式。因此&#xff0c;在进行浮点数的加减运算之前&#xff0c;需要统一浮点数的表达方式。这里我们主要对浮点数表示中的尾数M进行处理&#xff0c;要求0≤M<1&#xff0c;统一格式如下&#xff1a; 正数…...

opencascade 快速显示AIS_ConnectedInteractive源码学习

AIS_ConcentricRelation typedef PrsDim_ConcentricRelation AIS_ConcentricRelation AIS_ConnectedInteractive 简介 创建一个任意位置的另一个交互对象实例作为参考。这允许您使用连接的交互对象&#xff0c;而无需重新计算其表示、选择或图形结构。这些属性是从您的参考对…...

CentOS系统上安装单机版Redis教程

一、前言 1.1 为什么选择Redis&#xff1f; Redis不仅支持丰富的数据类型&#xff08;如字符串、哈希、列表、集合、有序集合等&#xff09;&#xff0c;还具有高性能、持久化、发布订阅、事务和Lua脚本等特点。这些优势使其成为分布式系统和高并发应用中的首选。 1.2 为什么…...

纯Java实现Google地图的KMZ和KML文件的解析

目录 前言 一、关于KMZ和KML 1、KMZ是什么 2、KML是什么 二、Java解析实例 1、POM.xml引用 2、KML 基类定义 3、空间对象的定义 4、Kml解析工具类 三、KML文件的解析 1、KML解析测试 2、KMZ解析测试 四、总结 前言 今天是六.一儿童节&#xff0c;在这里祝各位大朋友…...

k8s自定义资源你会创建吗

创建自定义资源定义 CustomResourceDefinition 当你创建新的 CustomResourceDefinition&#xff08;CRD&#xff09;时&#xff0c;Kubernetes API 服务器会为你所 指定的每一个版本生成一个 RESTful 的 资源路径。CRD 可以是名字空间作用域的&#xff0c;也可以是集群作用域的…...

CATIA二次开发VBA入门(4)——进程外开发环境搭建,vb.net在Visual Studio中开发,创建圆柱曲面的宏录制到二次开发案例

目录 引出vb.net和vb6.0 进程外开发环境搭建vb.net开发环境搭建《CATIA二次开发技术基础》模板 添加宏库引用 vs开发环境初步vs中的立即窗口对象浏览器 建立模板案例&#xff1a;创建一堆圆柱曲面第一步&#xff1a;录制宏第二步&#xff1a;代码精简第三步&#xff1a;for循环…...

c++字符串相关接口

c字符串相关接口 1.str2wstr(str转换wstr)2.wstr2str(str转换wstr)3.Utf8ToAsi(Utf8转换ANSI)4.AsiToUtf8(ANSI转换Utf8)5.stringformatA/stringformatW(按照指定的格式格式化字符串)6.GetStringBetween(获取cStart cEnd之间的字符串)7.Char2Int(char转int)8.Str2Bin(字符串转换…...

Maven打包错误:无效的源发行版:17

1. 报错问题 在用maven进行打包时&#xff08;clean & install&#xff09;&#xff0c;报如下错误&#xff1a; 一开始让我很摸不着头脑&#xff0c;我确定我的pom.xml&#xff0c;还有IDEA中的Project Settings是正确的。 2. 排查 尽管确定&#xff0c;但还是一个个排…...

【环境栏Composer】Composer常见问题(持续更新)

1、执行composer install提示当前目录中没有 composer.lock 文件时 No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information. Composer 在执行 install 命令时会…...

塑造更智慧的AI:策略与路径探索

提升数据质量&#xff1a; 数据清洗&#xff1a;去除数据中的异常值、缺失值、噪声等干扰因素&#xff0c;确保数据的准确性和一致性。数据标注&#xff1a;为数据集提供准确的标签&#xff0c;以便进行有监督学习。标注的质量直接影响模型的性能。数据增强&#xff1a;通过图像…...

软设之快速排序

快速排序是冒泡排序的改进算法 它采用的是分治法&#xff0c;基本思想是把原问题分解为若干规模更小但结构与原问题相似的子问题&#xff0c;通过递归解决这些子问题&#xff0c;然后将这些子问题的解组合成原问题的解。 它的步骤是 1.在待排序的n个记录中任取一个记录&…...

从零学算法2965

2965. 找出缺失和重复的数字 给你一个下标从 0 开始的二维整数矩阵 grid&#xff0c;大小为 n * n &#xff0c;其中的值在 [1, n2] 范围内。除了 a 出现 两次&#xff0c;b 缺失 之外&#xff0c;每个整数都 恰好出现一次 。 任务是找出重复的数字a 和缺失的数字 b 。 返回一个…...

【Mac版】Java生成二维码

软件版本 IntelliJ IDEA&#xff1a;2023.2 JDK&#xff1a;17 Tomcat&#xff1a;10.1.11 Maven&#xff1a;3.9.3 技术栈 servlet谷歌的&#xff1a;zxing 生成普通的黑白二维码在二维码中间添加一个小图标 github开源项目&#xff1a;qrcode qrcode开源项目的内部是基于z…...

ROS2自定义服务接口

ROS2自定义服务接口 在src/village_interface 下构建srv文件夹 src/village_interface/srv 下新建一个BorrowMoney.srv 遵循大小写编程规范 # 客户端请求 string name uint32 money # 中间这三个横杠很重要 不能删掉 --- # 服务端响应 bool success uint32 money接口编译 修改…...

linux /www/server/cron内log文件占用空间过大,/www/server/cron是什么内容,/www/server/cron是否可以删除

linux服务器长期使用宝塔自带计划任务&#xff0c;计划任务执行记录占用服务器空间过大&#xff0c;导致服务器根目录爆满&#xff0c;需要长期排查并删除 /www/server/cron 占用空间过大问题处理 /www/server/cron是什么内容&#xff1f;/www/server/cron是否可以删除&#xf…...

C++青少年简明教程:break语句、continue语句

C青少年简明教程&#xff1a;break语句、continue语句 break语句 只能用在switch语句和循环语句&#xff08;for循环、while循环和do-while循环&#xff09;中。作用&#xff1a;跳出switch语句或提前终止循环。 break语句的基本语法如下&#xff1a; break; break语句的示例…...

MySQL实战行转列(或称为PIVOT)实战sales的表记录了不同产品在不同月份的销售情况,进行输出

有一个sales的表&#xff0c;它记录了不同产品在不同月份的销售情况&#xff1a; productJanuaryFebruaryMarchProduct AJanuary10Product AFebruary20Product BJanuary5Product BFebruary15Product CJanuary8Product CFebruary12 客户需求展示为如下的样子&#xff1a; pro…...

牛客NC164 最长上升子序列(二)【困难 贪心+二分 Java/Go/PHP/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/4af96fa010c44638a7e112abf65f7237 思路 贪心二分 所谓贪心&#xff0c;就是往死里贪&#xff0c;所以对于最大上升子序列&#xff0c;结尾元素越小&#xff0c;越有利于后面接上其他的数&#xff0c;也就可能变…...

电子烟开发【恒压、恒有效算法】

恒压算法 pwm是通过软件模拟的 pwm满值运行是250全占空比 #define D_TARGET_AVERAGE_VOLTAGE 3500 //R_ADC1_Vout &#xff1a;发热丝两端AD值 //R_ADC_FVR &#xff1a;电池电压AD值 //FVR_VOLTAGE &#xff1a;电池AD参考电压 满电值AD //R_Smk1Duty &#xff1a;最后…...

基于Open3D的点云处理22-非阻塞可视化/动态可视化

官网测试用例:examples/python/visualization/non_blocking_visualization.py 非阻塞可视化,即实时更新点云数据; 如下,动态可视化ICP的匹配过程: import open3d as o3d import numpy as npif __name__ == "__main__":o3d.utility.set_verbosity_level(o3d.ut…...

C++面试题其一

C和C的区别 C和C都是广泛使用的编程语言&#xff0c;但它们有显著的区别&#xff1a; 语言范式&#xff1a; C&#xff1a;是一种过程化编程语言&#xff0c;强调过程和函数的使用。C&#xff1a;是一种多范式编程语言&#xff0c;支持面向对象编程、泛型编程和过程化编程。 …...

CentOS7某天的samba服务搭建操作记录(还没成功)

#CentOS7 yum软件仓库阿里云 samba服务器配置失败 sensors成功了 (花了200元组装H61测试机&#xff0c;75元的主板只有一块能用&#xff0c;垃圾板但又不完全能用&#xff09; 2024.5月的某天记录如下&#xff1a; https://blog.csdn.net/dszgf5717/article/details/53732182 …...

Qt Demo:基于TCP协议的视频传输Demo

目录 1.设计思路 2.Pro文件配置 3.头文件引入 4.界面设计 5.初始化设备函数 6.发起视频链接函数 7.初始化定时器模块函数 8.TCP链接模块函数 9.处理接收的数据线程函数 10.实现功能展示 设计思路 基于TCP协议的视频传输Demo&#xff0c;设计要实现的功能主要是TCP传输还有视频&…...

内存管理【C++】

内存分布 C中的内存区域主要有以下5种 栈&#xff08;堆栈&#xff09;&#xff1a;存放非静态局部变量/函数参数/函数返回值等等&#xff0c;栈是向下增长的【地址越高越先被使用】。栈区内存的开辟和销毁由系统自动执行 堆&#xff1a;用于程序运行时动态内存分配&#xff…...

D3D 顶点格式学习

之前D3D画三角形的代码中有这一句&#xff0c; device.VertexFormat CustomVertex.TransformedColored.Format; 这是设置顶点格式&#xff1b; 画出的三角形如下&#xff0c; 顶点格式是描述一个三维模型的顶点信息的格式&#xff1b;可以包含以下内容&#xff0c; 位置…...

gmssl vs2010编译

1、虚拟机win10 x64&#xff0c;离线安装vs2010和2010sp1补丁&#xff1b; 2、安装ActivePerl_v5.28.1.0000和nasm-2.16.03-installer-x64均是默认完整安装&#xff1b; nasm官网下载&#xff1a; Index of /pub/nasm/releasebuilds/2.16.03/win64https://www.nasm.us/pub/nas…...

容器化部署gitlab、jenkins,jenkins应用示例

一、容器化部署docker和docker conpose安装 Docker&Docker-compose的安装及部署_docker 20 使用什么版本docker-compose-CSDN博客 1.docker 安装脚本 cat >01_docker.sh<<EOF #!/bin/bash yum remove docker \docker-client \docker-client-latest \docker-co…...

基于STM32的轻量级Web服务器设计

文章目录 一、前言1.1 开发背景1.2 实现的功能1.3 硬件模块组成1.4 ENC28J60网卡介绍1.5 UIP协议栈【1】目标与特点【2】核心组件【3】应用与优势 1.6 添加UIP协议栈实现创建WEB服务器步骤1.7 ENC28J60添加UIP协议栈实现创建WEB客户端1.8 ENC28J60移植UIP协议并编写服务器测试示…...

用r语言处理 Excel数据当中的缺失值方法

以下是使用 R 编程语言处理 Excel 缺失数据的一些常见方法示例代码&#xff1a;&#xff08;无需循环&#xff09; 读取包含缺失数据的 Excel 文件 data <- read.csv(“your_file.csv”) 查看数据中是否有缺失值 sum(is.na(data)) 用平均值填充缺失值 data c o l u m …...