6-11知识点:数据结构——图
作者:互联网
最短路径问题——Floyd算法
一.过程演示
A(-1)/path(-1):不允许在除起点外的任何顶点中转(直达)
A(0)/path(0):允许在V0中转
A(1)/path(1):允许在V0、V1中转
A(2)/path(2):允许在V0、V1、V2中转
A表示:行到列的最短路径长度
A(-1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 6 | 13 |
V1 | 10 | 0 | 4 |
V2 | 5 | ∞ | 0 |
表示两个顶点之间的中转点,一开始不允许中转,写-1
path(-1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 |
#0:允许在V0中转
例:
V1到V2
不借助V0:4
借助V0:10+13=23
23>4,不修改
A(0)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 6 | 13 |
V1 | 10 | 0 | 4 |
V2 | 5 | 11 | 0 |
V2到V1借助V0中转
path(0)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 |
V2 | -1 | 0 | -1 |
即:每次选择更小的
用A(K-1) [i][j]表示上一轮从i到j的路径长度
通过K中转
每次判断A(K-1) [i][j]和A(K-1) [i][k]+A(K-1) [k][j]的大小关系,如果通过中转的路径更小,则更新当前轮(K轮)从i到j的A表
A(K) [i][j]=A(K-1) [i][k]+A(K-1) [k][j]
并修改path表中i到j的数据为k
path(K) [i][j]=k
#1:允许在V0、V1中转
A(1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 6 | 10 |
V1 | 10 | 0 | 4 |
V2 | 5 | 11 | 0 |
path(1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | 1 |
V1 | -1 | -1 | -1 |
V2 | -1 | 0 | -1 |
#2:允许在V0、V1、V2中转
A(2)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 6 | 10 |
V1 | 9 | 0 | 4 |
V2 | 5 | 11 | 0 |
path(2)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | 1 |
V1 | 2 | -1 | -1 |
V2 | -1 | 0 | -1 |
通过观察表得出
V1到V2的
最短路径长度为:4
最短路径为:V1→V2(-1表示直达)
V1到V0的最短路径:V1→V2→V0
二.代码实现
for(int k=0;k<n;k++)//以Vk为中转点
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)//i为行号,j为列号
{
if(A[i][j]>a[i]a[k]+a[k][j])
{
A[i][j]=a[i]a[k]+a[k][j];
path[i][j]=k;
}
}
}
}
三.时间复杂度、空间复杂度
时间复杂度:O(|V|3)
空间复杂度:O(|V|2) (需要A和path两个辅助矩阵)
四.进阶
A(-1)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | ∞ | 1 | ∞ | 10 |
V1 | ∞ | 0 | ∞ | 1 | 5 |
V2 | ∞ | 1 | 0 | ∞ | 7 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
path(-1)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | -1 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 | -1 | -1 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
#0:允许在V0中转
A(0)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | ∞ | 1 | ∞ | 10 |
V1 | ∞ | 0 | ∞ | 1 | 5 |
V2 | ∞ | 1 | 0 | ∞ | 7 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
path(0)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | -1 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 | -1 | -1 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
#1:允许在V0、V1中转
A(1)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | ∞ | 1 | ∞ | 10 |
V1 | ∞ | 0 | ∞ | 1 | 5 |
V2 | ∞ | 1 | 0 | 2 | 6 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
path(1)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | -1 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 | 1 | 1 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
#2:允许在V0、V1、V2中转
A(2)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | 2 | 1 | 3 | 7 |
V1 | ∞ | 0 | ∞ | 1 | 5 |
V2 | ∞ | 1 | 0 | 2 | 6 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
V0到V3新添加了中转点V2导致path[0][3]更新(原来V0到V3无路径,现在变为V0→V2→V1→V3),因此中转点写最新加入的2
path(2)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | 2 | -1 | 2 | 2 |
V1 | -1 | -1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 | 1 | 1 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
#3:允许在V0、V1、V2、V3中转
A(3)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | 2 | 1 | 3 | 4 |
V1 | ∞ | 0 | ∞ | 1 | 2 |
V2 | ∞ | 1 | 0 | 2 | 3 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
path(3)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | 2 | -1 | 2 | 3 |
V1 | -1 | -1 | -1 | -1 | 3 |
V2 | -1 | -1 | -1 | 1 | 3 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
#4:允许在V0、V1、V2、V3、V4中转
A(4)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | 0 | 2 | 1 | 3 | 4 |
V1 | ∞ | 0 | ∞ | 1 | 2 |
V2 | ∞ | 1 | 0 | 2 | 3 |
V3 | ∞ | ∞ | ∞ | 0 | 1 |
V4 | ∞ | ∞ | ∞ | ∞ | 0 |
path(4)=
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
V0 | -1 | 2 | -1 | 2 | 3 |
V1 | -1 | -1 | -1 | -1 | 3 |
V2 | -1 | -1 | -1 | 1 | 3 |
V3 | -1 | -1 | -1 | -1 | -1 |
V4 | -1 | -1 | -1 | -1 | -1 |
通过表格得到
V0到V4的最短路径长度A[0][4]=4
最短路径:path[0][4]=
V0→V3→V4=
(V0→V2)→V3→V4=
V0→(V2→V1)→V3→V4
注:
(1)相邻两顶点之间的path若不为-1,应展开
(2)以上书写为便于理解,并非标准解题过程
五.Floyd算法用于负权图
#-1:不允许中转
A(-1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 1 | 7 |
V1 | ∞ | 0 | -5 |
V2 | ∞ | ∞ | ∞ |
path(-1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 |
#0:允许在V0中转
A(0)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 1 | 7 |
V1 | ∞ | 0 | -5 |
V2 | ∞ | ∞ | ∞ |
path(0)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | -1 |
V1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 |
#1:允许在V0、V1中转
A(1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 1 | -4 |
V1 | ∞ | 0 | -5 |
V2 | ∞ | ∞ | ∞ |
path(1)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | 1 |
V1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 |
#2:允许在V0、V1、V2中转
A(2)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | 0 | 1 | -4 |
V1 | ∞ | 0 | -5 |
V2 | ∞ | ∞ | ∞ |
path(2)=
V0 | V1 | V2 | |
---|---|---|---|
V0 | -1 | -1 | 1 |
V1 | -1 | -1 | -1 |
V2 | -1 | -1 | -1 |
通过表格,V0到V2的最短路径长度为:|-4|=4
最短路径为:V0→V1→V2
六.缺点
通过回路无限循环,总路径长度会越来越小,因此Floyd 算法不能解决带有“负权回路”的图(有负权值的边组成回路),这种图有可能没有最短路径
七.BFS算法、Dijkstra算法、Floyd 算法对比总结
注:
(1)BFS算法的时间复杂度与广度优先遍历相同
邻接矩阵:O(|V|²)
邻接表:O(|V|+|E|)
(2)也可用Dijkstra 算法求各顶点间的最短路径,重复 |V| 次即可:分别以每个顶点作为源顶点,求该顶点到达其他顶点的路径。时间复杂度为O(|V|)*O(|V|2),即总的时间复杂度也是O(|V|3)
标签:11,知识点,中转,V0,V1,V2,path,数据结构,1V2 来源: https://blog.csdn.net/weixin_45825865/article/details/116355081