数据结构--最短路径 Floyd算法

数据结构--最短路径 Floyd算法

F l o y d 算法:求出每⼀对顶点之间的最短路径 \color{red}Floyd算法:求出每⼀对顶点之间的最短路径 Floyd算法:求出每⼀对顶点之间的最短路径

使⽤动态规划思想,将问题的求解分为多个阶段

对于n个顶点的图G,求任意⼀对顶点 V i → V j V_i \to V_j Vi→Vj 之间的最短路径可分为如下⼏个阶段:

#初始:不允许在其他顶点中转,最短路径是?

#0:若允许在 V0 中转,最短路径是?

#1:若允许在 V0、V1 中转,最短路径是?

#2:若允许在 V0、V1、V2 中转,最短路径是?

...

#n-1:若允许在 V0、V1、V2 ...... Vn-1 中转,最短路径是?

Floyd算法是一种用于寻找图中任意两个节点之间最短路径的算法,它的步骤如下:

  1. 创建一个二维数组dist,用于存储任意两个节点之间的最短路径长度。初始时,dist的值为图中两个节点之间的直接路径长度,如果两个节点之间没有直接路径,则设置为无穷大。
  2. 创建一个二维数组path,用于存储任意两个节点之间的最短路径的中间节点。初始时,path的值为起始节点到终点节点的直接路径上的终点节点。
  3. 使用三重循环,遍历所有节点,每次循环中选择一个节点k作为中间节点,更新dist和path数组的值。
    a. 对于每对节点i和j,如果通过节点k可以使得从节点i到节点j的路径更短,则更新dist[i][j]的值为dist[i][k] + dist[k][j],并更新path[i][j]的值为节点k。
    b. 如果dist[i][j]的值变小了,说明找到了一条更短的路径,需要更新path[i][j]的值为节点k。
  4. 重复步骤3,直到遍历完所有节点。
  5. 根据path数组,可以构建任意两个节点之间的最短路径。

以上就是Floyd算法的基本步骤。

Floyd算法的时间复杂度为 O ( n 3 ) O(n^3) O(n3),其中n为节点的个数。

若 A ( k − 1 ) [ i ] [ j ] > A ( k − 1 ) [ i ] [ k ] + A ( k − 1 ) [ k ] [ j ] 则 A ( k ) [ i ] [ j ] = A ( k − 1 ) [ i ] [ k ] + A ( k − 1 ) [ k ] [ j ] ; path ⁡ ( k ) [ i ] [ j ] = k 否则 A ( k ) 和 path ( k ) 保持原值 \begin{aligned} &\text{若}&& \mathrm{A}^{(k-1)}[i][j]\mathrm{>}\mathrm{A}^{(k-1)}[i][k]\mathrm{+}\mathrm{A}^{(k-1)}[k][j] \\ &\text{则}&& \mathbf{A}(k)[i][j]=\mathbf{A}^{(k-1)}[i][k]+\mathbf{A}^{(k-1)}[k][j]; \\ &&&\operatorname{path}^{(k)}[i][j]=k \\ &\text{否则}&& A^{(k)}\text{ 和 path}^{(k)}\text{ 保持原值} \end{aligned} 若则否则A(k−1)[i][j]>A(k−1)[i][k]+A(k−1)[k][j]A(k)[i][j]=A(k−1)[i][k]+A(k−1)[k][j];path(k)[i][j]=kA(k) 和 path(k) 保持原值

V0到V4 最短路径⻓度为 A[0][4]=4

通过path矩阵递归地找到完整路径:

注:

Floyd算法可以⽤于负权图

Floyd 算法不能解决带有"负权回路"的图(有负权值的边组成回路),这种图有可能没有最短路径

eg:

代码

cpp 复制代码
void floyd()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
 {
dist[i][j] = map[i][j],
path[i][j] = 0; 
 }
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(dist[i][k] + dist[k][j] < dist[i][j])
 {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = k; //中转点
 }
 }

知识点回顾与重要考点

注:也可⽤ Dijkstra 算法求所有顶点间的最短路径,重复 |V| 次即可,总的时间复杂度也是 O ( ∣ V ∣ 3 ) O(|V|^3) O(∣V∣3)

相关推荐
自我意识的多元宇宙9 分钟前
树、森林——树与二叉树的应用(哈夫曼树的构造)
数据结构
|_⊙37 分钟前
C++ 智能指针
开发语言·c++
代码中介商41 分钟前
C语言指针深度解析:从数组指针到函数指针
c语言·开发语言
memcpy01 小时前
LeetCode 2452. 距离字典两次编辑以内的单词【暴力;字典树】中等
算法·leetcode·职场和发展
水蓝烟雨1 小时前
2071. 你可以安排的最多任务数目
数据结构·链表
Jasmine_llq1 小时前
《B4356 [GESP202506 二级] 数三角形》
开发语言·c++·双重循环枚举算法·顺序输入输出算法·去重枚举算法·整除判断算法·计数统计算法
山栀shanzhi1 小时前
在做直播时,I帧的间隔(GOP)一般是多少?
网络·c++·面试·ffmpeg
王老师青少年编程1 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【排序贪心】:魔法
c++·算法·贪心·csp·信奥赛·排序贪心·魔法
wearegogog1231 小时前
基于和差波束法的单脉冲测角MATLAB实现
人工智能·算法·matlab
AI科技星2 小时前
灵魂商数(SQ) · 全域数学统一定义【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算