有权图的单源最短路径

和无权图不同,因为有权图的边上带权值,所以在计算最短路径时会出现和无权图不同的情况,无权图边的权值默认是1,有权图则不是,所以有权图的单源最短路径上,顶点的个数不一定是最少的。我们来看一个例子:有权图的单源最短路径_第1张图片

假设以V1为源点,V6为终点,那么V1到V6的单源最短路径是哪一条?是V1->V2->V5->V8->V6。和无权图不同,有权图在找最短路时要考虑路径边上权值的问题。乍一看V1到V6经过顶点数最少的是路径V1->V3->V6,但是边上权值之和等于5+6=11。而V1->V2->V5->V8->V6的权值之和等于1+3+2+2=8。所以从V1到V6的单源最短路径是V1->V2->V5->V8->V6。

因为有权图的边上带权值特点,所以会出现一种特别的情况,例如如果我们以V5为源点,V8为终点找最短路径的话。。。。那么这条最短路径就会在V5->V8->V7->V5。。。。上不断循环。

有权图的单源最短路径_第2张图片

因为V5->V8->V7->V5一次循环后权值之和等于-1,两次循环后权值之和等于-2,所以随着每次走过一圈后,权值之和都会越来越小。这种路径有个名称叫“负值圈”。

求有权图的单源最短路径代码和无权图的算法有点相似,因为其实无权图可以看作是特殊的有权图,无权图可看作所有的边的权值都等于1,而且两者在求最短路径时都是按照递增的顺序找出到各个顶点的最短路径。解决有权图的单源最短路径算法叫Dijkstra算法。下面来看一下Dijkstra算法的模板

有权图的单源最短路径_第3张图片

每次Pop出一个顶点给V后,把它记录进collected数组里,然后判断V的每一个邻接点W,判断源点S到V的距离加上边的权值,如果距离小于源点到W的距离(第197行),就更新一下做为最短距离(第198行)。同时更新路径(第199行)。

Dijkstra算法的完整代码:

有权图的单源最短路径_第4张图片

有权图的单源最短路径_第5张图片

你可能感兴趣的:(C/C++,数据结构)