Floyd——Warshall

Floyd------Warshall

多源最短路径:一次性可以算出任意两点之间最短距离

相比较之前的Dijkstra,这个可以算负边权(但是注意不要有负环),当然鱼和熊掌不可兼得,随着三重循环的展开,空间复杂度自然有点复杂,效率相比较Dijkstra来说就比较低了。

这里我们想要求a到b的距离最短,要么是a直接到b,要么a,b之间还有一个k,从a到k再到b,从而判断那个最短我们就选哪个。如上图,4和3之间的距离原本是12,那如果我们通过1来当过客的话,我们通过1,路程进一步缩短为5+6=11。在如果我们把2也拉入过客我们通过1,2,路程进一步缩短为5+2+3=10,那么10就是我们4到3的最短路径了。

下面我们来模拟一下方便理解:

1 2 3 4
1 0 2 6 5
2 ∞\infty∞ 0 3 ∞\infty∞
3 7 ∞\infty∞ 0 1
4 5 ∞\infty∞ 12 0

我们先允许1号经过:

dis3 1+dis1 2=9<∞\infty∞,dis4 1+dis1 \[\]=7<∞\infty∞,dis4 1+dis1 3=11<12,

1 2 3 4
1 0 2 6 5
2 ∞\infty∞ 0 3 ∞\infty∞
3 7 9 0 1
4 5 7 11 0

接下来我们允许2号也经过:

dis1 2+dis2 3=5<6,dis4 2+dis2 3=10<11,

1 2 3 4
1 0 2 5 5
2 ∞\infty∞ 0 3 ∞\infty∞
3 7 9 0 1
4 5 7 10 0

然后以此类推······我们就得到了

复制代码
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
const int N=105,INF=0x3f3f3f3f;
int dis[N][N];
int n,m;
signed main()
{
	cin>>n>>m;
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=n;i++)
	dis[i][i]=0;
	for(int i=0;i<m;i++)
	{
		int a,b,w;
		cin>>a>>b>>w;
		dis[a][b]=min(dis[a][b],w);
		dis[b][a]=min(dis[b][a],w);
	}
		for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	for(int i=1;i<=n;i++)
	{
		if(dis[1][i]==INF) cout<<"-1"<<" ";
		else cout<<dis[1][i]<<" ";
	}
	return 0;
}

最后要注意的是k要在最外层哦~~

相关推荐
带多刺的玫瑰1 小时前
Leecode#9刷题之回文数
数据结构·算法
泯泷1 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 3 篇:从栈式 VM 到寄存器式 VM:为什么我们选择寄存器
前端·javascript·算法
泯泷2 小时前
第 4 篇:让 VM 支持变量:Slot、Environment 与 TDZ
前端·javascript·算法
Asize2 小时前
54. 螺旋矩阵
算法
Asize2 小时前
73. 矩阵置零
算法
微露清风3 小时前
快慢指针算法学习记录
学习·算法·快慢指针