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

【算法基础】Dijkstra 算法

定义:

  • g [ i ] [ j ] g[i][j] g[i][j] 表示 v i v_i vi 到 $v_j $的边权重,如果没有连接,则 g [ i ] [ j ] = ∞ g[i][j] = \infty g[i][j]=
  • d i s [ i ] dis[i] dis[i] 表示 v k v_k vk 到节点 v i v_i vi 的最短长度, d i s [ k ] = 0 , d i s [ i ] = ∞ , i ≠ k dis[k] = 0, dis[i]=\infty, i \neq k dis[k]=0,dis[i]=,i=k.

目标:

  • 计算出 d i s dis dis 数组,也就是任何点到 v k v_k vk 的距离。

step1 : 更新 v k v_k vk 的所有邻居节点 v y v_y vy的最短路径; 即: d i s [ y ] = g [ k ] [ y ] dis[y] = g[k][y] dis[y]=g[k][y]
step2 : 找出 这些邻居节点中路径最短的 d i s [ i 1 ] dis[i1] dis[i1]. 此时 d i s [ i 1 ] dis[i1] dis[i1] 一定已经是最短的了,可以用反证法来证明。
step3 : 找出 v i 1 v_{i1} vi1 的邻居节点 y ′ y' y, 如果 d i s [ i 1 ] + g [ i 1 ] [ y ′ ] < d i s [ y ′ ] dis[i1]+g[i1][y'] < dis[y'] dis[i1]+g[i1][y]<dis[y], 则更新 d i s [ y ′ ] = d i s [ i 1 ] + g [ i 1 ] [ y ′ ] dis[y'] =dis[i1]+g[i1][y'] dis[y]=dis[i1]+g[i1][y], 否则不更新。
step4 : 找出 k , i 1 k,i1 k,i1之外的 d i s [ i ] dis[i] dis[i] 最小的值 d i s [ i 2 ] dis[i2] dis[i2], 重复之前的更新过程,知道取完所有点为止。

code :

leecode 743
朴素写法:

class Solution:def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:g = [[inf for _ in range(n)] for _ in range(n)]  # 邻接矩阵for x, y, d in times:g[x - 1][y - 1] = ddis = [inf] * nans = dis[k - 1] = 0  # 起始节点done = [False] * n   #是否确定为最短while True:x = -1# 找到最短的 done 是用来排除已经确定的那些点的。完成后x 记录当前最短距离的那个点。# 起始为 kfor i, ok in enumerate(done):if not ok and (x < 0 or dis[i] < dis[x]):x = i# 没有找到,也就是所有点已经全部确定后。if x < 0:return ans  # 最后一次算出的最短路就是最大的# 无法到达if dis[x] == inf:  # 有节点无法到达return -1# 因为每次都是递增的,而答案是要求最大的最短路径。ans = dis[x]  # 求出的最短路会越来越大done[x] = True  # 最短路长度已确定(无法变得更小)# 更新 x 的邻居节点的最短距离。for y, d in enumerate(g[x]):# 更新 x 的邻居的最短路dis[y] = min(dis[y], dis[x] + d)

堆优化 Dijkstra:

class Solution:def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:g = [[] for _ in range(n)]  # 邻接表for x, y, d in times:g[x - 1].append((y - 1, d))dis = [inf] * ndis[k - 1] = 0h = [(0, k - 1)]   # 二元组 (dis[i], i)while h:dx, x = heappop(h)  # 找到最短路径的 x 和其相应的 disif dx > dis[x]:  # x 之前出堆过,continue# 这里continue 是因为 对于一个x 由于更新了多次dis, 堆中科恩那个存在多个 dx, 对于那些较大的dx, 不再使用的意思。# 更新邻居for y, d in g[x]:new_dis = dx + dif new_dis < dis[y]:dis[y] = new_dis  # 更新 x 的邻居的最短路heappush(h, (new_dis, y))mx = max(dis)return mx if mx < inf else -1

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 乘积量化pq:将高维向量压缩 97%
  • SSM 整合(Spring + MyBatis;Spring + Spring MVC)
  • VUE中setup()
  • Python爬虫速成之路(3):下载图片
  • 【常见开源库的二次开发】基于openssl的加密与解密——Base的编解码(二进制转ascll)(二)
  • 1219:马走日
  • STM32 不同时钟频率有什么不同的影响
  • 云计算实训室的核心功能有哪些?
  • Xcode 16 beta3 真机调试找不到 Apple Watch 的尝试解决
  • 人工智能算法工程师(中级)课程12-PyTorch神经网络之LSTM和GRU网络与代码详解1
  • BL201分布式I/O耦合器连接Profinet网络
  • Win11鼠标卡顿 - 解决方案
  • [word] word表格跨页断开实现教程 #职场发展#媒体
  • pycharm如何debug for循环里面的错误值
  • COD论文学习 ZoomNext
  • Android框架之Volley
  • Apache的基本使用
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JWT究竟是什么呢?
  • leetcode98. Validate Binary Search Tree
  • PhantomJS 安装
  • Solarized Scheme
  • vuex 学习笔记 01
  • 今年的LC3大会没了?
  • 目录与文件属性:编写ls
  • 思考 CSS 架构
  • 智能合约Solidity教程-事件和日志(一)
  • Java总结 - String - 这篇请使劲喷我
  • raise 与 raise ... from 的区别
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #APPINVENTOR学习记录
  • #define,static,const,三种常量的区别
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $.proxy和$.extend
  • (附源码)php投票系统 毕业设计 121500
  • (黑马点评)二、短信登录功能实现
  • (十三)Flask之特殊装饰器详解
  • (四)库存超卖案例实战——优化redis分布式锁
  • (一)kafka实战——kafka源码编译启动
  • (一一四)第九章编程练习
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)
  • (转)四层和七层负载均衡的区别
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .md即markdown文件的基本常用编写语法
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • // an array of int
  • @media screen 针对不同移动设备
  • [20181219]script使用小技巧.txt
  • [ACM独立出版]2024年虚拟现实、图像和信号处理国际学术会议(ICVISP 2024)
  • [AI Google] 使用 Gemini 取得更多成就:试用 1.5 Pro 和更多智能功能
  • [BJDCTF2020]The mystery of ip1
  • [BZOJ3211]:花神游历各国(小清新线段树)
  • [C]编译和预处理详解