【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)

Dijkstra算法是用来求解从某个源点到其他各顶点的最短路径(单源最短路径)。

下面的Dijkstra算法的讲解都是基于这个有向图,在遇到其他问题可以类比。

算法的基本思想:

把图中的定点分成两组,第一组包括已确定最短路径的顶点,初始时只含有一个源点,记为集合S;第二组包括尚未确定的最短路径的顶点,记为V-S;按最短路径长度递增的顺序逐个把V-S中的顶点加到S中去,直至从v0出发可以到达的所有顶点都包括在S中。

【讲到这里要打断一下:我最初就是不能理解这个“按最短路径长度的递增顺序”(1)这个顺序到底是什么顺序?(2)哪个点到哪个点的最短路径长度?(3)如果是那个已经确定的源点到其他点的最短路径,但是源点并不是到每个点都有路径,在开始给邻接矩阵复制的时候,有的位置是INF,那这个怎么比较????当时心里有无数个问号,找了很多博客,大家都没有详细说明(内心:这个这么好理解?我这么弱?)下面就会一一解答上面的问号。】

接着上面,在这个过程中,总保持v0到第一组S中各顶点的最短路径都不大(小于等于)与v0到第二组V-S的任何顶点的最短路径长度,第二组的顶点对应距离值是从v0到此顶点的只包括第一组S的顶点中为中间顶点的最短路径长度。对于S中任意一点 j,v0到j的路径长度皆小于v0到V-S中任意一点的路径长度。(这也与上面用红色标注的按照最短路径长度的递增顺序

始点 终点 最短路径 路径长度
A B (A,C,B) 19
  C (A,C) 4
  D (A,C,F,D) 25
  E (A,C,B,E) 29
  F (A,C,F) 12

该表格表示:A到其余各点的最短路径

看到这里:上述所说的按照对端路径长度的递增顺序逐个把V-S中的顶点加到S中去,但是在拿到一个有向图时,我们怎么可能一眼看出路径长度是多少?需要代码求解。

为了实现该串代码,与要设置需要设置距离向量d[ ](即:源点到该点的最短路径),以及保存路径的向量p[](即:它的前一个点是谁(官方:最短路径上第i个顶点的前驱顶点序号))。

算法的具体步骤可描述如下:

(1)初始化:包括对第一组(集合S:目前集合S只有{v0})的初始化与对距离向量d的初始化(用邻接矩阵中相应的值进行赋值)。

(2)从第二组V-S的顶点中选取一个距离值最小的顶点v加入S,。接着对V-S中的所有顶点值进行修改,修改的方法是,对于V-S中的任意一个顶点k,若图中有边<v,k>,且v0到v的距离加上<v,k>边上的权值之和小于v0到k的距离值,则用“v0到v的距离加上<v,k>边上的权值代替顶点k原来的距离值”,(v作为中间点);反之,则顶点k的距离值保持不变。

d[k] = min(d[k],d[v]+edges[v][k])

【我的理解:就是一开始d[k]中肯定就和邻接矩阵中的值一样,有数字,也有INF(即不存在到该点的路径,但是随着S集合中不断加入顶点(按照最短路径的长度递增顺序),源点通过加入的这些顶点就可以到达更多的顶点,每加入一个顶点,就要算一下通过这个刚刚加入的中间点,v0到其他点的距离是否有变短,如果有,则修改相应的值,反之,则保持不变。要保证加入到S中的每个点,源点v0到它们的路径长度是最短的。】

(3)若集合V-S已空,则结束算法。若V-S不为空,则返回步骤(2)。

有向网G采用邻接矩阵存储结构

#include <stdio.h>
#include <stdlib.h>
#define  M 20
#define FINITY 50000
typedef struct 
{
	char vexs[M];
	int edges[M][M];
	int n,e;
}Mgraph;

创建网络的邻接矩阵算法

void creat(Mgraph *g,int c)
{
	int i,j,k,w;
	FILE *f;
	f=
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值