Dijkstra--解决非负权边的单源最短路算法

前言

这是之前写过的一篇 D i j k s t r a Dijkstra Dijkstra算法博客的重置版,最近正好在复习,发现了一些事实错误(我菜爆了),再加上当时用的是富文本编辑器写的,整体排版不太好看,于是干脆推到重写,以下是原文前言部分:

最近一直忙,没有时间写算法博客(其实是去水数据结构去了),今天睡前写一篇图论的基础算法吧,叫 D i j k s t r a Dijkstra Dijkstra,是由荷兰计算机科学家 E . W . D i j k s t r a E.W.Dijkstra E.W.Dijkstra于1959年提出的,因此叫 D i j k s t r a Dijkstra Dijkstra算法.是求从一个源点到其余各顶点的最短路径算法,即单源最短路算法,解决的是图论中最短路径问题.

原理

对于一个有 m m m条边, n n n个顶点的图,我们先定义如下描述,以表示一个图的某些关系:

源点 s t st st,表示算法所求最短路的出发顶点;

点集 V V V,表示图中所有点构成的集合,其中 ∣ V ∣ = n |V| = n V=n;

边集 E E E,表示途中所有边构成的集合,其中 ∣ E ∣ = m |E| = m E=m;

数组 d i s [ ] dis[] dis[],表示源点 s t st st到其余点的最短路径,数组大小为 n n n;

三元组 &lt; u , v , w &gt; &lt;u,v,w&gt; <u,v,w>,表示有一条从 u u u v v v,权值为 w w w的边,即 u → v = w u \to v = w uv=w;

我们选择一个源点 s t st st,求它到其余所有点的最短路径,算法描述如下:

  1. 初始化: 将源点到的所有顶点的最短距离设为 + ∞ +\infin +,到自身为 0 0 0: ∀ i ∈ V , d i s [ i ] → + ∞ , d i s [ s t ] = 0 \forall i \in V, dis[i] \to + \infin, dis[st] = 0 iV,dis[i]+,dis[st]=0.
  2. 找点松弛边: 寻找一个离源点 s t st st最近的且未使用过的点 i i i,以该点为中间点松弛源点 s t st st到其他点的最短路径,松弛操作描述如下: ∀ &lt; i , v , w &gt; ∈ E , d i s [ v ] = m i n ( d i s [ v ] , d i s [ i ] + w ) \forall &lt;i,v,w&gt; \in E,dis[v] = min(dis[v],dis[i] + w) <i,v,w>E,dis[v]=min(dis[v],dis[i]+w),标记 i i i为用过的点.
  3. 重复2,直到所有点都用过(松弛进行了 n − 1 n-1 n1次).

在算法描述里提到了松弛这个概念,那么,什么是松弛呢?

所谓松弛,即寻找一个顶点 t t t,使得从 s t → e st \to e ste的最短路长度能通过 t t t中转变成 s t → t → e st \to t \to e stte,且长度缩短,那么我们就说 s t → e st \to e ste的最短路通过t这个点松弛成功.比如 1 → 2 1 \to 2 12有长为 9 9 9的路径, 1 → 3 1 \to 3 13有长为 1 1 1的路径, 3 → 2 3 \to 2 32有长为 3 3 3的路径,则通过 3 3 3松弛

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值