码迷,mamicode.com
首页 > 编程语言 > 详细

最短路径的部分算法实现和复杂度

时间:2017-03-23 18:49:50      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:.net   数组   理解   dijkstra   环路   检测   test   算法实现   写法   

参考:

各种最短路算法时间分析参考:http://blog.csdn.net/zxy_snow/article/details/6270468

带权最短路算法分析:https://www.renfei.org/blog/weighted-shortest-path.html

 

本题题意:算出起点到所有点的最短路总距离,注意本题有重边

例如:1 3 5

     1 3 2

那么只能取最短的边

 

本题代码图的储存方式皆使用静态邻接表,n代表点数,m代表边数:

技术分享

...

 

技术分享

 

本题中所有算法都有一个dis[n]的数组,下标表示点的编号,数组表示起点到其他每个点的距离

1.Bellman-Ford

时间复杂度:O(VE),效率一般
适用范围:(很广)允许存在负权边,能够判断图中是否存在从源点可到达的负权环路

主要思想是使用n-1次循环,每次循环将m条边遍历,若可以通过这条边(假设为u到v)

将源点到v的距离,缩短到源点到u再通过这条边到v的距离,更新dis[v]。

核心代码:(本题没使用静态邻接表只用了结构数组记录边的信息)

技术分享

....

技术分享

代码用时:155ms

2. SPFABellman-Ford 队列优化)

图解:http://blog.csdn.net/qq_25605637/article/details/50858414

时间复杂度:最坏也是O(kE),k为一较小常量。效率很高
适用范围:(较广),允许存在负权边,但不允许负权环路
代码复杂程度:较易,需队列

主要思想是使用队列去掉bellman的一些不必要判断,采用了一个vis数组标记进入队列的元素。如果这条边(u到v)可以更新dis值,而且v没被标记,将v加入队列,标记v。但本题可能由于代码使用数据结构的不同并没有达到优化效果

核心代码:

技术分享

代码用时:166ms

3.Dijkstra

 

适用范围:(一般)不允许存在负权边适用范围:(一般)不允许存在负权边
这个算法复杂度取决于"取最小"(Extract-min)操作使用的算法
Extract-min操作                时间复杂度               代码复杂程度
顺序检测所有点决定最小值           O(V^2)                        一般

 

主要思想 采用n次循环将边进行松弛,每次循环选择dis数组中距离最短的并且未被标记的点松弛,然后对以这点为起点的所有边松弛dis数组,标记该点。

 

技术分享

 

4. Dijkstra(优先队列优化)

适用范围:(一般)不允许存在负权边
这个算法复杂度取决于"取最小"(Extract-min)操作使用的算法

使用Binary-Heap(优先队列)       O((V+E)lgV)                 较复杂

 

主要思想是使用优先队列优化每次寻找最短边的操作,其实就是把查找的复杂度降到Ologn?,因为优先队列的数据结构是堆。

 

需要构建一个结构作为队列元素和重载一个比较函数,还需要运用初始化列表,这部分写法比较难理解,暂且当做模板使用。

队列元素:

技术分享

技术分享

代码用时:159ms

最短路径的部分算法实现和复杂度

标签:.net   数组   理解   dijkstra   环路   检测   test   算法实现   写法   

原文地址:http://www.cnblogs.com/Jadon97/p/6606530.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!