【最短路径】之Dijkstra算法
https://www.liuchuo.net/archives/2357
【最短路径】之Dijkstra算法
最短路径
- 单源最短路径:计算源点到其他各顶点的最短路径的长度
- 全局最短路径:图中任意两点的最短路径
- Dijkstra、Bellman-Ford、SPFA求单源最短路径
- Floyed可以求全局最短路径,但是效率比较低
- SPFA算法是Bellman-Ford算法的队列优化
- Dijkstra算法不能求带负权边的最短路径,而SPFA算法、Bellman-Ford算法、Floyd-Warshall可以求带负权边的最短路径。
- Bellman-Ford算法的核心代码只有4行,Floyd-Warshall算法的核心代码只有5行。
- 深度优先遍历可以求一个点到另一个点的最短路径的长度
Dijkstra算法
- 三种附加考法:第一标尺是距离,如果距离相等的时候,新增第二标尺
- 新增边权(第二标尺),要求在最短路径有多条时要求路径上的花费之和最小
- 给定每个点的点权(第二标尺),要求在最短路径上有多条时要求路径上的点权之和最大
- 直接问有多少条最短路径
增加一个数组num[],num[s] = 1,其余num[u] = 0,表示从起点s到达顶点u的最短路径的条数为num[u]
- 例子:比如说又要路径最短,又要点权权值最大,而且还要输出个数,而且还要输出路径
- of course, 可以不用这么麻烦,用Dijkstra求最短路径和pre数组,然后用深度优先遍历来获取想知道的一切,包括点权最大,边权最大,路径个数,路径
- 因为可能有多条路径,所以Dijkstra部分的pre数组使用
vecto<int> pre[maxv];
-
- 既然已经求得pre数组,就知道了所有的最短路径,然后要做的就是用dfs遍历所有最短路径,找出一条使第二标尺最优的路径
-
- 解释:
- 对于递归边界而言,如果当前访问的结点是叶子结点(就是路径的开始结点),那么说明到达了递归边界,把v压入temppath,temppath里面就保存了一条完整的路径。如果计算得到的当前的value大于最大值,就path = temppath,然后把temppath的最后一个结点弹出,return ;
- 对于递归式而言,每一次都是把当前访问的结点压入,然后找他的pre[v][i],进行递归,递归完毕后弹出最后一个结点
- 计算当前temppath边权或者点权之和的代码:
-
- 计算路径直接在Dijkstra部分写就可以
- 例子:计算最短距离的路径和最小花费
-
🍀取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣🍀
🍀每天都要有收获 (*/ω\*)🍀
🍀后悔是没有用的,从现在开始,立刻马上去做(≧∀≦)ゞ🍀