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要在最外层哦~~