利用Dijkstra算法实现记录每个结点的所有最短路径

最近在做PAT时发现图论的一些题目需要对多条最短路径进行筛选,一个直接的解决办法是在发现最短路径的时候就进行判断,选出是否更换路径;另一个通用的方法是先把所有的最短路径记录下来,然后逐个判断。前者具有一定的难度并且不好排查BUG,因此我设计了一种基于Dijkstra的记录所有最短路的简捷算法,用于解决此类题目。

我们知道,Dijkstra是解决单源最短路问题的,并且最基本的算法仅能求出最短路的长度,而不能输出路径,本文基于Dinjkstra进行改进,使之能记录源点到任意点的所有最短路径。

使用vector<int>来记录一条路径,因为每个结点可能有多条最短路径,因此把这些路径都装在一个vector中,因此可以用一个vector<vector<int> >来表示一个结点的所有最短路径,把所有结点的最短路径都存放起来,又需要一个vector容器,因此所有结点的所有最短路径的集合可以用vector<vector<vector<int> > >来表示。

约定:结点编号为0到N-1,源点为0,到每个点的最短距离存储在数组minD[N]中。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Dijkstra算法是一种用于求解带权有向图中单源最短路径算法。具体步骤如下: 1. 初始化:将起s加入集合S,将与s直接相连的加入集合T,记录从s到这些的距离。 2. 选择T中距离s最近的v,将v加入集合S。 3. 更新T中的距离:对于T中的每个w,如果从s到v再到w的距离比从s直接到w的距离短,就更新从s到w的距离。 4. 重复步骤2和3,直到T为空。 最终得到的结果是从起s到每个最短路径和路径长度。 例如,给定以下带权有向图: ![image.png](attachment:image.png) 以结点A为起,应用Dijkstra算法,得到以下结果: 结点 | 最短路径 | 路径长度 ---|---|--- A | A | 0 B | AB | 1 C | AC | 2 D | ABD | 4 E | ABE | 3 因此,从结点A到结点B的最短路径为AB,路径长度为1;从结点A到结点C的最短路径为AC,路径长度为2,以此类推。 ### 回答2: Dijkstra算法是一种用于求解带权有向连通图中单源最短路径算法,它以贪心的策略逐步确定到源最短路径。下面我们将结点称为顶,边称为弧。 Dijkstra算法流程: 1. 初始化: 首先,给定一个带权有向连通图,并且选择一个源,通常将源最短路径长度设置为0,其他顶最短路径长度设置为无穷大。 2. 确定最短路径: 遍历所有未确定最短路径的顶,选择其中距离源最近的顶,将其确定为最短路径。 3. 更新最短路径长度: 以该最短路径为中心,更新与其邻接的顶最短路径长度,即若从最短路径v到其邻接的顶w的距离d(v,w)加上v的最短路径长度小于w的最短路径长度,则更新w的最短路径长度为d(v,w)+v的最短路径长度。 4. 标记已确定最短路径: 将最短路径v标记为已经确定了最短路径,即可以保证其最短路不会再发生变化。 5. 重复2到4的步骤,直到所有顶最短路径都已确定。 Dijkstra算法可以用优先队列(也称堆)来实现,以减少时间复杂度。 用Dijkstra算法输出从源到其余结点最短路径和路径长度: 1. 初始化: 给定一个带权有向连通图和一个源s。用数组dist记录s与所有顶之间的最短路径长度,用数组path记录v的前一个顶u在s到v的最短路径上。 2. 算法操作: 首先将dist[s]置为0,其他所有顶的dist值置为无穷大。把源s加入到一个优先队列Q中。 3. 迭代: 在每次迭代中,从Q中取出一个dist值最小的顶u,然后遍历与u相邻接的所有顶v,并更新它们的dist值和path数组。若加入顶v可以通过u到达,则比较dist[u]+w(u,v)和dist[v]的值,若前者更小,则更新dist[v]和path[v]分别为dist[u]+w(u,v)和u。最后将顶v加入到Q中。 4. 输出: 重复迭代过程,直到Q为空。此时dist数组记录着源s到所有其他顶最短路径长度,path数组记录每个最短路径上的前一个顶。可以根据path数组从后往前依次输出每个最短路径Dijkstra算法时间复杂度为O(ElogV),其中E为边数,V为顶数。因此该算法适用于边相对较少而顶较多的情形。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值