Dijkstra 最短路笔记
前言
前两天新阵地联盟的 T15 出了个自己发明的 Dijkstra,然后我非常开心地没有拿到分数。于是打算重写笔记。
Dijkstra 是由 E.W.Dijkstra 发明的,用于求非负权图上的单源最短路算法。
算法过程
Dijkstra 的想法很简单。要求 \(s\) 到 \(t\) 的最短路,我们一开始令 \(dis_s = 0\),其他点的 \(dis\) 为 \(+ \infty\)(一般在 OI 中,我们令其为 0x3f3f3f3f)。
然后从 \(s\) 开始跑 bfs,对于每个结点 \(u\),我们遍历其下一个结点 \(v\),其中 \(w\) 为 \(u\) 到 \(v\) 的边权,如果 \(dis_v > dis_u + w\),那么我们对 \(v\) 进行松弛操作。并且将结点 \(v\) 放入以 \(dis\) 排序的小根堆中。
正确性证明
由于我不会,证毕。
时间复杂度
使用堆优化后,平均时间复杂度为 \(O(m \log m)\)。
朴素算法下时间复杂度为 \(O(n^2)\)
示例代码
Python
# 我们已经用链式前向星把图存在了 g[] 中,head[] 为每个结点的边所在链表的头指针,规定 g[] = [v, w, nxt],其中 nxt = 0 表示空指针
# 使用 dis 储存到每个结点的距离,初始时已经初始化为 0x3f3f3f3f
import heapq
from collections import defaultdict
def dijkstra(st, ed):
dis = defaultdict(lambda: float('inf'))
dis[st] = 0
q = [(0, st)]
vis = set()
while q:
_, u = heapq.heappop(q)
if u in vis:
continue
vis.add(u)
cur = head[u]
while cur:
v, w, nxt = g[cur]
if dis[v] > dis[u] + w:
dis[v] = dis[u] + w
heapq.heappush(q, (dis[v], v))
cur = nxt
return dis[ed]

浙公网安备 33010602011771号