Floyd-Warshall算法(弗洛伊德算法)·C/C++·基础图论

不同于Dijkstra算法,Floyd-Warshall算法可以求出一张图中任意两点的距离。

该算法由1978年图灵奖获得者斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

在这里插入图片描述

伯特·弗洛伊德先生

图灵奖:作为计算机权威奖项之一,被誉为计算机界的“诺贝尔”奖。截至至2020年11月,姚期智先生是我国唯一一位获此殊荣的计算机科学家。

在这里插入图片描述

姚期智先生

算法的核心思想:动态规划。

设置状态:d[k][i][j]的含义是,假如思考的路径包含了k号点(0->k)(注释:未必非要从K顶点走),那么最优的答案是多少呢?

现在,假设所有的之前的状态方案已经转移完成:【k-1】层次的点,那么现在对于【K】的转移:

应该考虑这个问题:(1)不走K顶点,那么就是d[k][i][j]=d[k-1][i][j];(2)走了K顶点:那么状态转移就是d[k][i][j]=d[k-1][i][k]+d[k-1][k][j];

所以最终的状态转移方程是:d[k][i][j]=min(d[k-1][i][j],d[k-1][i][k]+d[k-1][k][j]);

当k=0的时候,那么意思就是直接相连那么这个值就是cost(I,j);(路径上的花费)

现在,如果我们把i,j转化成坐标轴的x轴,y轴,把k化为z轴。

那么在三维的坐标里面。k是从下往上不会突然返回的,那么实际上可以不再考虑k的值,从而直接更新d[i][j]的值,那么就不需要三维数组了。最后的状态转移方程d[i][j]=min(d[i][j],d[i][k]+d[k][j]);

那么现在思考,怎么维护i,j,k之间的关系呢?

假设三重循环是i,j,k的顺序。

从(1,1)(1,2)(1,3)…的顺序开始计算的时候。

那么当(1,3)就应该需要两个(1,2)(2,3)的状态转移过来,显然(2,3)是没有被计算过的。

所以这样的循环是错误的。

实际上,在刚刚设计数组的时候,把三维变成二维的时候,就已经考虑到k是会一直往上的。

那么按照k,i,j的时候来循环,直观的意思就是,当包含了0->k的顶点的时候,d[i][j]的值是多少?

这样的话,上面的错误便完美解决,所以最终循环按照k,i,j来进行即可。(思路上也应该是这样思考)

最终代码实现:(缺少读入和输出)

在这里插入图片描述

核心部分的实现

Bilibili同名UP主,CSDN同步更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值