【C++】Floyd算法

算法简介

F l o y d Floyd Floyd算法是多源最短路径算法,即可以求任意两点的最短路径,它基于动态规划的思想,时间复杂度为 O ( n 3 ) O(n^3) O(n3)
它的创始人罗伯特·弗洛伊德 ( R o b e r t   W . F l o y d ) (Robert\ W.Floyd) (Robert WFloyd)将此算法命名为 F l o y d − W a r s h a l l Floyd-Warshall FloydWarshall算法,简称 F l o y d Floyd Floyd算法。罗伯特·弗洛伊德是1978年图灵奖得主,他同时还创立了堆排序算法。

算法思想

F l o y d Floyd Floyd算法的核心思想就是用每个点作为中间结点去更新任意点的最短路径。

它的核心思想是 d p [ k ] [ i ] [ j ] = m i n ( d p [ k − 1 ] [ i ] [ j ] , d p [ k − 1 ] [ i ] [ k ] + d p [ i − 1 ] [ k ] [ j ] ) dp[k][i][j]=min(dp[k-1][i][j],dp[k-1][i][k]+dp[i-1][k][j]) dp[k][i][j]=min(dp[k1][i][j],dp[k1][i][k]+dp[i1][k][j])

其中 d p [ 0 ] [ i ] [ j ] = m a p [ i ] [ j ] dp[0][i][j]=map[i][j] dp[0][i][j]=map[i][j]也就是初值为邻接矩阵。

核心代码

假设目前 m a p [ 0 ] [   ] [   ] map[0][\ ][\ ] map[0][ ][ ]存的是邻接矩阵。

void Floyd(){
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				map[k][i][j]=min(
					map[k-1][i][j],
					map[k-1][i][k]+map[k-1][k][j]
				);
			}
		}
	}
}

值得注意的是 k k k在最外层,这是因为 F l o y d Floyd Floyd本质是动态规划算法,做的实际上是二维动态规划。第一个维度的 k k k只表示第 k k k次动态规划的结果,而第二个第三个维度的 k k k则表示以第 k k k个点作为中间结点。

优化

F l o y d Floyd Floyd算法可以在空间上进行优化,这才是平常使用的 F l o y d Floyd Floyd算法。
d p [ k ] [ i ] [ j ] = m i n ( d p [ k − 1 ] [ i ] [ j ] , d p [ k − 1 ] [ i ] [ k ] + d p [ i − 1 ] [ k ] [ j ] ) dp[k][i][j]=min(dp[k-1][i][j],dp[k-1][i][k]+dp[i-1][k][j]) dp[k][i][j]=min(dp[k1][i][j],dp[k1][i][k]+dp[i1][k][j])中,在第 k k k轮时,与 k k k相关的路径长度是不会改变的,所以无需保存前一个状态。

void Floyd(){
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				map[i][j]=min(
					map[i][j],
					map[i][k]+map[k][j]
				);
			}
		}
	}
}

总结

F l o y d Floyd Floyd算法的因为要求任意两点最短路径,所以空间复杂度就是存图的 O ( n 2 ) O(n^2) O(n2),因为三重循环则导致了时间复杂度为 O ( n 3 ) O(n^3) O(n3) F l o y d Floyd Floyd算法适用于带负权的图,但不能出现负权环。因此, F l o y d Floyd Floyd算法不适用于大量数据的计算,他简单易实现的同时也注定了效率上得做取舍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cout0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值