在最短路问题中,若是咱们面对的是稠密图(十分稠密的那种,好比说全链接图),计算多源最短路的时候,Floyd算法才能充分发挥它的优点,不折不扣战胜SPFA和Dijkstra算法
在别的最短路问题中都不推荐使用这个算法数组
咱们以一道单源最短路题目介绍一下在输入数据为边表的状况下的Floyd使用状况,若是直接给了邻接矩阵的话,直接无脑求就能够了函数
在这里,咱们把Floyd算法的功能补全,实现了一个打印最短路径的函数并加入了求无向图的最小环的功能(通过至少两个定点,权值和最小)spa
看定义:code
int n,m,s,mina=INF; int d[maxn][maxn],mp[maxn][maxn],p[maxn][maxn];
n个点m条边和源点s,最小环初始化为INFblog
而后d是最短路的答案数组,mp是初始地图数组,p是记录两个点之间的衔接点k,用来打印路径递归
而后是初始化:string
void init() { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=mp[i][j]=INF; for(int i=1;i<=n;i++) d[i][i]=mp[i][i]=0; }
这里注意,若是给的是边表,必需要这么作,若是给的是矩阵,能够直接忽略这个函数了it
而后是Floyd算法:io
void floyd() { for(int k=1;k<=n;k++) { for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) mina=min(d[i][j]+mp[j][k]+mp[k][i],mina); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(d[i][k]<INF&&d[k][j]<INF) d[i][j]=min(d[i][j],d[i][k]+d[k][j]),p[i][j]=k; } }
若是单纯忽略mina的求解过程,这就是一个裸的,Floyd
咱们再看一下路径是怎么打印的,其实很显然:
void output(int i,int j) { if(i==j) return; if(p[i][j]==0) printf("%d ",j); else{output(i,p[i][j]);output(p[i][j],j);} }
递归的思路仍是很明显的
咱们给出完整的实现:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1005; 6 const int maxm=2005; 7 const int INF=0x7fffffff; 8 int n,m,s,mina=INF; 9 int d[maxn][maxn],mp[maxn][maxn],p[maxn][maxn]; 10 void init() 11 { 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 d[i][j]=mp[i][j]=INF; 15 for(int i=1;i<=n;i++) d[i][i]=mp[i][i]=0; 16 } 17 void floyd() 18 { 19 for(int k=1;k<=n;k++) 20 { 21 for(int i=1;i<k;i++) 22 for(int j=i+1;j<k;j++) 23 mina=min(d[i][j]+mp[j][k]+mp[k][i],mina); 24 25 for(int i=1;i<=n;i++) 26 for(int j=1;j<=n;j++) 27 if(d[i][k]<INF&&d[k][j]<INF) 28 d[i][j]=min(d[i][j],d[i][k]+d[k][j]),p[i][j]=k; 29 } 30 } 31 void output(int i,int j) 32 { 33 if(i==j) return; 34 if(p[i][j]==0) printf("%d ",j); 35 else{output(i,p[i][j]);output(p[i][j],j);} 36 } 37 int main() 38 { 39 scanf("%d%d%d",&n,&m,&s); 40 int x,y,z; 41 init(); 42 for(int i=1;i<=m;i++) {scanf("%d%d%d",&x,&y,&z);mp[x][y]=d[x][y]=min(z,d[x][y]);} 43 floyd(); 44 for(int i=1;i<=n;i++) printf("%d ",d[s][i]); 45 return 0; 46 }
请注意,请注意,请注意
在不保证没有重边的状况下,必定要有
mp[x][y]=d[x][y]=min(z,d[x][y]);
不然凉凉