Dijkstra最短路算法

上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”。本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的1号顶点到2、3、4、5、6号顶点的最短路径。

与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下。

我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下。

我们将此时dis数组中的值称为最短路的“估计值”。

既然是求1号顶点到其余各个顶点的最短路程,那就先找一个离1号顶点最近的顶点。通过数组dis可知当前离1号顶点最近是2号顶点。当选择了2号顶点后,dis[2]的值就已经从“估计值”变为了“确定值”,即1号顶点到2号顶点的最短路程就是当前dis[2]值。为什么呢?你想啊,目前离1号顶点最近的是2号顶点,并且这个图所有的边都是正数,那么肯定不可能通过第三个顶点中转,使得1号顶点到2号顶点的路程进一步缩短了。因为1号顶点到其它顶点的路程肯定没有1号到2号顶点短,对吧O(∩_∩)O~

既然选了2号顶点,接下来再来看2号顶点有哪些出边呢。有2->3和2->4这两条边。先讨论通过2->3这条边能否让1号顶点到3号顶点的路程变短。也就是说现在来比较dis[3]和dis[2]+e[2][3]的大小。其中dis[3]表示1号顶点到3号顶点的路程。dis[2]+e[2][3]中dis[2]表示1号顶点到2号顶点的路程,e[2][3]表示2->3这条边。所以dis[2]+e[2][3]就表示从1号顶点先到2号顶点,再通过2->3这条边,到达3号顶点的路程。

我们发现dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此dis[3]要更新为10。这个过程有个专业术语叫做“松弛”。即1号顶点到3号顶点的路程即dis[3],通过2->3这条边松弛成功。这便是Dijkstra算法的主要思想:通过“边”来松弛1号顶点到其余各个顶点的路程。

同理通过2->4(e[2][4]),可以将dis[4]的值从∞松弛为4(dis[4]初始为∞,dis[2]+e[2][4]=1+3=4,dis[4]>dis[2]+e[2][4],因此dis[4]要更新为4)。

刚才我们对2号顶点所有的出边进行了松弛。松弛完毕之后dis数组为:

接下来,继续在剩下的3、4、5和6号顶点中,选出离1号顶点最近的顶点。通过上面更新过dis数组,当前离1号顶点最近是4号顶点。此时,dis[4]的值已经从“估计值”变为了“确定值”。下面继续对4号顶点的所有出边(4->3,4->5和4->6)用刚才的方法进行松弛。松弛完毕之后dis数组为:

继续在剩下的3、5和6号顶点中,选出离1号顶点最近的顶点,这次选择3号顶点。此时,dis[3]的值已经从“估计值”变为了“确定值”。对3号顶点的所有出边(3->5)进行松弛。松弛完毕之后dis数组为:

继续在剩下的5和6号顶点中,选出离1号顶点最近的顶点,这次选择5号顶点。此时,dis[5]的值已经从“估计值”变为了“确定值”。对5号顶点的所有出边(5->4)进行松弛。松弛完毕之后dis数组为:

最后对6号顶点所有点出边进行松弛。因为这个例子中6号顶点没有出边,因此不用处理。到此,dis数组中所有的值都已经从“估计值”变为了“确定值”。

最终dis数组如下,这便是1号顶点到其余各个顶点的最短路径。

时间: 2024-11-05 06:20:44

Dijkstra最短路算法的相关文章

最短路算法

最短路径问题旨在寻找图中两节点之间的最短路径,常用的算法有以下四种.注意是把图处理成无向还是有向 Dijkstra's (权值非负) 1 Dijkstra's算法解决的是图中单个源点到其它顶点的最短路径.只能解决权值非负 2 Dijkstral只能求出任意点到达源点的最短距离(不能求出任意两点之间的最短距离),同时适用于有向图和无向图,复杂度为O(n^2). 3算法的过程: 1设置顶点集合S并不断的作贪心选择来选择扩充这个集合.一个顶点属于集合S当且仅当从源点到该点的最短路径长度已知 2 初始时

只有五行的Floyd最短路算法

暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表示这条公路的长短.请注意这些公路是单向的.我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径.这个问题这也被称为"多源最短路径"问题. 现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储.比如1号城市到2号城市的路程为2,则设e[

Dijkstra算法 c语言实现

 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等. 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 初始时,

Dijkstra最短路径算法实现代码_C 语言

Dijkstra的最短路径算法是基于前驱顶点的最短路径计算的,整体上来讲还是比较简单的,下面是代码: 复制代码 代码如下: #include <iostream>#include <vector>#include <limits> void shortestpath( const std::vector <std::vector< short> >& paths, int from, std::vector< short>&a

HDU 1535 Invitation Cards:多源点到单点最短路

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题目: Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1044    Accepted Submission(s): 459 Problem Description In the age of te

HDU 3339 In Action:最短路+背包

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3339 题目: Problem Description Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the number of nuclear weapons have soared across the globe. Nowadays,the crazy bo

HDU 1595 find the longest of the shortest(枚举,最短路)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1595 题目: find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 667    Accepted Submission(s): 220 Problem Description Ma

vb.net 中的短路

我问"你学过vb.net吗?"你说:"学过,而且用的特别熟!"我问:"那你知道vb.net的短路概念吗?"你会说:"当然了,不就是逻辑与或上那些#$%^&*?......" 我说:"对,就是那些东西!我给你一段程序看看你能搞定吗?" "No problem !"you said . 下面是段程序,很简单,看你能不能搞定. If Not Equals(txtAge.Text, St

HDU 1385 Minimum Transport Cost:最短路,打印字典序路径

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1385 题目大意: 有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度. 如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费). 现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和. 求最小花费,如果有多条路经符合,则输出字典序最小的路径. 分析与总结: 1.   这题的关键在于按照字典序输出路径. 假设有 1---