[笔记]Dijkstra算法正确性证明

最近做了一些题,感觉对算法更深刻的理解是比套板子更深层次的,在这个层次上解决问题,思路会更加清晰。比如P5687 [CSP-S2019 江西] 网格图题解)这道题就是网格图的最小生成树,解法就建立在普通Kruskal的基础上,当时想了挺久也没想出来,看了题解才豁然开朗。所以各算法总是要回顾回顾的~

除了做题,没事想一想算法的工作原理,也会对算法有更深的理解。以后我会多写一些对一些算法的剖析和理解(可能并不是特别严谨,主要以可读性为主,以供随时回顾)。


Dijkstra的算法全过程

  • 初始定义\(S=\varnothing,T=V\)
  • 重复下列操作,直到\(T=\varnothing\)
    • \(T\)中找到到\(S\)距离最近的节点\(u\),此时\(u\)的最短路确定。
    • \(u\)\(T\)中取出,转入\(S\),并对\(u\)的邻接节点进行松弛操作。

Dijkstra正确性证明

对于节点\(u\),我们要证明它加入\(S\)时,我们确定下来的最短路是实际的最短路。

反证,假设在操作\(1\)结束后,有\(x\in T\),使得存在\(T\rightarrow\dots\rightarrow x\rightarrow u\),使得\(dis[x]+v<dis[u]\),由于边权\(v\)非负,所以一定有\(dis[x]<dis[u]\),那么\(x\)一定提前于\(u\)进入\(T\)并对\(u\)进行松弛了,与\(x\notin T\)矛盾。

同时这也解释了Dijkstra为什么不能处理负权边:如果存在负权边,我们就不能推出\(dis[x]<dis[u]\)

以前有段时间疑惑过为什么不能让所有边都加某个值来去除负权边,然而这样很显然是错误的:

posted @   Sinktank  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2025-3-6 6:10:36 TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.
点击右上角即可分享
微信分享提示