Floyd详解
先来看一组样例
Input
5 8 1 4 5 1 3 2 3 4 3 4 2 2 4 5 1 1 5 8 2 5 4 3 2 6
Output
0 7 2 5 6 -1 0 -1 -1 4 -1 5 0 3 4 -1 2 -1 0 1 -1 -1 -1 -1 0
我们先将dis全部变成极大值(很重要)
但是如果i = j,dis[i][j] = 0;
我们不妨顺着代码的执行来手动模拟一下(前方高能!!!)
这个可真难画,将就着看吧。
k = 1 :
以1为中间节点来扩展
按照代码中写的来看,我们看到以1为中间节点可以扩展出从1到3,1到4,1到5的值。
此时已经没有点可以与1相连。
以2为中间节点的时候,这时候1和2还不能直接相连。所以不能扩展。
再看别的能扩展的i 和 j,
如下图我们可以更新3->2->5和4->2->5;
k = 3 :
从1到2的路径为极大值,如果通过3到达2,长度为8,8<=INF,所以dis[1][2]更新成8。
同理,dis[1][4] = 5;
此时,以3为中间节点的操作已经完成。
后面就不画图了,自行脑补吧
k = 4 :
可以通过4更新1->4->5 , 3->4->5 , 1->4->2 , 3->4->2.
同理,我们就可以把所有的点都更新完。
完整代码
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #define INF 214748364 using namespace std; int n, m, s, t; int dis[1005][1005]; int main() { scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { dis[i][j] = (i == j)?0:INF; } } for(int i=1; i<=m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); dis[u][v] = w; } for(int k=1; k<=n; k++) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(dis[i][j] > dis[i][k]+dis[k][j]) { dis[i][j] = dis[i][k]+dis[k][j]; } } } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(dis[i][j] != INF) printf("%d ", dis[i][j]); else printf("-1 "); } printf("\n"); } }
作者:wlz
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:Mystical-W
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可