最短路之dijkstra算法

问题

已知一张有向图,求出一个点到其他点的最短路径,也就是单源最短路径的问题。单源最短路问题是指给定一张有向图G=(V,E),V是点集,E是边集,|V|=n,|E|=m,节点以[1,n]之间的连续整数编号,(x,y,z)描述一条从x出发,到达y,长度为z的有向边。设一点为起始点,dist[i]表示从起点到i的最短路径长度。

最短路之dijkstra算法_第1张图片

解析

Dijkstra算法基于贪心思想,它只适用于所有边的长度都为非负整数的图。当边长z为都为负数时,全局最小值不可能更新,所以开始时我们选出的节点x必须满足:dist[x]已经为起点到x的最短路径。我们不断选择全局最小值进行标记和拓展,最终可以得到起点到每个节点的最短路径的长度。
图解:
最短路之dijkstra算法_第2张图片
最短路之dijkstra算法_第3张图片
最短路之dijkstra算法_第4张图片
最短路之dijkstra算法_第5张图片
最短路之dijkstra算法_第6张图片
最短路之dijkstra算法_第7张图片
最短路之dijkstra算法_第8张图片
最短路之dijkstra算法_第9张图片
所以a到h的最短距离为18。

设计

1.初始化起点s的dist[s]=0,其余节点的dist值为inf。
2.找出一个为被标记过的、dist[x]最小的节点x,然后标记节点x。
3.扫描节点x的所有出边(x,y,z),若dist[y]>dist[x]+z,则用dist[x]+z更新dist[y]。

分析

首先dijksrta算法求单源最短路径为了确保计算每个点的dist值,要运行n-1次,每次要找出未被标记的最小dist[x],并且拓展更新,要遍历n次,因此算法复杂度为O(n2)。
如果使用链式前向星存图,使用二叉堆也就是优先队列对dist数组进行维护,可以用O(logn)的时间获取最小值并且删除,在使用O(logn)的时间更新和拓展,最终可以在O((m+n)logn)的时间内实现堆优化的dijkstra算法。

源码

https://github.com/Geedhayb/Geed/blob/master/dijkstra.cpp

你可能感兴趣的:(算法分析)