常用图论算法模板(2)Floyd算法求最短路

dijkstra适合用于求图中给定两点间的距离,并具有优良的效率。但是如果在需要得知任意两点间的最短路距离时,每次询问都跑dijkstra显然不是最优策略。
而求任意两点间距离时,我们可以使用 Floyd 算法来求解,该算法存在三重循环:枚举中间点 k 、起点 x 、终点 y :每次使用 x 与 k 和 k 与 y 之间的距离更新 x 与 y 之间的距离。通俗来说,Floyd 算法检查了两个点之间是否能通过走其他点(k)来获得更短的距离。很明显时间复杂度为 O ( n 3 ) O(n^3) O(n3)
代码模板(c++)

for(int k = 1; k<=n; k++)
    for(int i = 1; i<=n; i++)
        for(int j = 1; j<=n; j++)
            g[i][j] = min(g[i][j], g[i][k] + g[k][j]);

其中 g[i][j] 代表了从 i 出发走向 j 的最短路径距离,因此,Floyd 更适合用于邻接矩阵的情况。
Floyd 也可以用来求解传递闭包问题
传递闭包问题:假设有三个数字 a、b、c,已知 a > b a > b ab b > c b > c b>c,问 a 与 c 的大小关系。我们可以将其抽象成一个图论问题, a > b a > b ab 那么代表从 b 向 a 有一条单向边, b > c b > c b>c 代表从 c 向 b 有一条单向边,那么问题就转化成了从 c 是否能走到 a。同样可以使用 Floyd 解决:

g[b][a] = 1, g[c][b] = 1;
for(int k = 1; k <= n; k ++ )
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= n; j ++ )
            if(g[i][k] && g[k][j]) g[i][j] = 1;
cout << (g[c][a] ? "Yes" : "No") << '\n';
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值