Floyd-Warshall(最短路问题)

Floyd-Warshall(多源最短路)

问题的提出

已知一个带权有向图,求任意两个顶点之间的最短距离
在这里插入图片描述
现在我们需要一个数据结构将图抽象化,本题我们使用一个 n ∗ n n*n nn邻接矩阵e(二维数组,该题目有4个顶点,故 n = 4 n=4 n=4 )存储图的信息,二维数组的每个元素的取值如下:
e [ i ] [ j ] = { 0 , i = j ∞ , &lt; i , j &gt; ∉ e w i j , &lt; i , j &gt; ∈ e e[i][j]=\left\{ \begin{aligned} 0,&amp;&amp; {i=j}\\ ∞,&amp;&amp; {&lt;i,j&gt;\notin e}\\ w_{ij}, &amp;&amp;{&lt;i,j&gt;\in e} \end{aligned} \right. e[i][j]=0,,wij,i=j<i,j>/e<i,j>e

可到如下的二维数组:

0264
03
701
5120

至此我们完成了问题的抽象化处理

运用Floyd算法求解

算法的核心步骤是:要让任意两点 a , b a,b a,b 之间的距离a->b尽可能的小,我们需要引入第三个点 c c c 作为中转点,然后看看a->b->c的值是否比a->b小,若是则将a->b更新为a->b->c的值。这一过程用一专业术语描述为“松弛”。

枚举所有的点作为中转点,重复上述步骤

用图解能够更加直观地描述这一过程:

起初a到b的距离为10

起初a到b的距离为10,为当前最短距离

在这里插入图片描述

引入第三个点 c,发现通过 c,a 到b只需要 3+4=7,更新 a 到 b 的最短距离为 7

在我们之前已经构建好的数据结构中,我们可以将这一过程描述为:

对于每个 i , j , k , ( 1 &lt; i , j , k &lt; 4 ) i, j, k,(1&lt;i, j, k&lt;4) i,j,k(1<i,j,k<4)执行e[i][j] = min(e[i][k] + e[k][j], e[i][j])

用代码实现如下:

for(int k = 1; k <= n; k++)//枚举中转点
		for(int i = 1; i <= n; i++)//枚举起点
			for(int j = 1; j <= n; j++)//枚举终点
				e[i][j] = min(e[i][k] + e[k][j], e[i][j]);//状态更新

执行完所有步骤后,我们的邻接矩阵已经被更新为:

0254
9034
6801
57100

这样一来,每一个e[i][j]的值都是i点到j点的最短距离了

算法评价

  1. 遍历所有起点 i i i 和终点 j j j 的时间复杂度 O ( n 2 ) O(n^2) O(n2),采用松弛操作,对在 i i i j j j 之间的所有其他点进行一次松弛。所以总时间复杂度为 O ( n 3 ) O(n^3) O(n3);
  2. 可以解决带负权图的最短路问题,但不能解决带负权环图的最短路问题
  3. 算法易于理解,编写简单
  4. 较高的复杂度导致该算法不适合海量数据的处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值