问题:给定一个带权有向图G与源点v,求从源点v到G其他顶点的最短路径,并限定各边上的权值大于0
可以采用狄克斯特拉(Dijkstra)算法求解
基本思想(看不懂也没关系![c45ea0e335294ef99e744f0a9e7b9b29.png](https://img-blog.csdnimg.cn/c45ea0e335294ef99e744f0a9e7b9b29.png)
![ace9c081b173445e881b22a08f0ca96b.png](https://img-blog.csdnimg.cn/ace9c081b173445e881b22a08f0ca96b.png)
,先往下看)
设G=(V,E)是一个带权有向图,把图中的顶点集合V分成两组,第一组为已经求出求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径v,…u,就将顶点u加入集合S中,直到全部顶点都加入S中,算法就算结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序,依次把第二组的顶点加入S中。
算法具体步骤(按我自己的理解)
步骤1:每次从标记的节点中选择距离出发点最近的节点,标记,收录到最优路径集合中。
步骤2:计算刚加入的节点A的临近节点B,(不包含标记节点),若(节点A的距离+节点A到节点B的边长)<节点B的距离,就更新节点B的距离和前面点。
例:求下图从点0到点6的最短路径长度
可以列出如下表格,第一列为节点,第二列为该节点到源点0的距离(0到自身的距离为0,其他先设为 ∞ ),第三列为该节点的前一节点。
从源点0出发有三条路径,分别为0-->1,0-->2,0-->3,距离分别为4,6,6 。将节点1,2,3到源点0的距离更新。(下一步从节点到源点0的距离(已经更新的)比较小的值出发,如下图节点1到源点0的距离比其他两个节点到源点0的距离小,那么下一步就从节点1出发)
节点 | 该节点到源点0的距离 | 该节点的前一节点 |
0 | 0 | |
1 | ∞ 4 | 0 |
2 | ∞ 6 | 0 |
3 | ∞ 6 | 0 |
4 | ∞ | |
5 | ∞ | |
6 | ∞ |
接着就从节点1开始出发,从节点1出发有两条路径分别是1-->2,1-->4。其中节点2到源点0的距离5比原来的6小,那么就将节点2到源点0的距离由6更新为5,节点4到源点0距离由∞ 更新为11,节点2和节点4到源点0的距离更新则将节点2和节点4的前一节点更新为节点1。(下一步从节点到源点0的距离(已经更新的)比较小的值出发,如下图节点2到源点0的距离比节点4到源点0的距离小,那么下一步就从节点4出发)
节点 | 该节点到源点0的距离 | 该节点的前一节点 |
0 | 0 | |
1 | ∞ 4 | 0 |
2 | ∞ 6 5 | 0 1 |
3 | ∞ 6 | 0 |
4 | ∞ 11 | 1 |
5 | ∞ | |
6 | ∞ |
接着从节点2出发,从节点2出发有两条路径,分别是2-->4,2-->5。其中节点4到源点0的距离是11与之前的距离11相同不更新,从节点5到源点0的距离由∞更新为9,节点5到源点距离0更新则将节点5的前一节点更新为节点2。(下一步从节点到源点0的距离(已经更新的)比较小的值出发,如下图节点5到源点0的距离比节点4到源点0的距离小,那么下一步就从节点5出发)
节点 | 该节点到源点0的距离 | 该节点的前一节点 |
0 | 0 | |
1 | ∞ 4 | 0 |
2 | ∞ 6 5 | 0 1 |
3 | ∞ 6 | 0 |
4 | ∞ 11 | 1 |
5 | ∞ 9 | 2 |
6 | ∞ |
接着从节点5出发,从节点5出发有两条路径,分别是5-->4,5-->6。其中节点4到源点0的距离是10比之前的距离11小,那么就将节点4到源点0的距离由11更新为10,从节点6到源点0的距离由∞更新为17,节点4和节点6到源点0的距离更新则将节点4和节点6的前一节点更新为节点5.(下一步从节点到源点0的距离(已经更新的)比较小的值出发,如下图节点4到源点0的距离比节点6到源点0的距离小,那么下一步就从节点4出发)
节点 | 该节点到源点0的距离 | 该节点的前一节点 |
0 | 0 | |
1 | ∞ 4 | 0 |
2 | ∞ 6 5 | 0 1 |
3 | ∞ 6 | 0 |
4 | ∞ 11 10 | 1 5 |
5 | ∞ 9 | 2 |
6 | ∞ 17 |
最后从节点4出发,从节点4出发只有一条路径是4-->6,从节点6到源点0的距离是16比之前的15小,那么从节点6到源点0的距离由17更新为16,节点6到源点0的距离更新则将节点6的前一个节点更新为节点4。以上全部过程结束
节点 | 该节点到源点0的距离 | 该节点的前一节点 |
0 | 0 | |
1 | ∞ 4 | 0 |
2 | ∞ 6 5 | 0 1 |
3 | ∞ 6 | 0 |
4 | ∞ 11 10 | 1 5 |
5 | ∞ 9 | 2 |
6 | ∞ 17 16 | 4 |
上述过程求出了最短距离,那么我们就可以倒推出最短距离的路径是0-->1-->2-->5-->4-->6
以上是Dijkstra算法的算法分析,如果各位没理解可以看这个B站视频(我就是通过这个视频理解的)https://www.bilibili.com/video/BV1zz4y1m7Nq/?spm_id_from=333.999.0.0&vd_source=03eabc5b86b6a93efebb7477181513ce
编程小白的第一个博客,希望各位大佬可以多多支持