《经典图论算法》弗洛伊德算法(Floyd)

摘要:

1,Floyd算法的介绍和实现步骤

2,Floyd算法的代码实现和优化

3,Floyd算法最短路径打印

4,Floyd算法为什么要先遍历中间顶点 k 

1,Floyd算法的介绍和实现步骤

在前面我们讲过迪杰斯特拉算法Bellman-Ford算法以及SPFA算法,这些都是求单源点最短路径,也就是从计算从一个点到其他所有点的最短路径。而弗洛伊德(Floyd-Warshall)算法是求多源点最短路径的,就是求任意两个顶点之间的最短距离,可以有负权边都不能有负权回路。

我们来思考这样一个问题,如果知道 A 到 B 的距离是 x ,这个 x 可能是一个确定的值,也可能是无穷大,怎么才能使 x 的值变小呢?

唯一的解决方式就是找一个中转点 C ,判断 A 到 C 的距离加上 C 到 B 的距离是否小于 A 到 B 的距离,如果小于,就更新 A 到 B 的值,如果不小于, A 到 B 的值就不变。

如下图所示,A 到 B 的直线距离是 9 ,如果经过顶点 C 中转,距离就会变成 7 。

d1dc9278b1fb55e84e65d9370abe9257.png

只需要把所有的点都作为中转点枚举一遍即可,很明显这是一道动态规划的问题,我们定义 dp[k][i][j] 表示经过前 k 个顶点从 i 到 j 的最短距离。

1,如果不经过第 k 个顶点中转,那么:

      dp[k][i][j]=dp[k-1][i][j]。

2,如果经过第 k 个顶点中转,那么:

      dp[k][i][j]=dp[k-1][i][k]+dp[k-1][k][j]。

只需要取他们的最小值即可,也就是:

dp[k][i][j] = min(dp[k - 1][i][j], dp[k - 1][i][k] + dp[k - 1][k][j]);

我们来画个图看下:

ab78a87fbd38d80f78f5adc42676a855.png

54fd0b6c6db8966d92d52241de50e88a.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

数据结构和算法

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

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

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

打赏作者

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

抵扣说明:

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

余额充值