详解:Floyd算法本质即为判断点 i->j 过程中,添加辅助点 k,通过不断比较点 i->j 与 i->k->j 的大小关系去实现最短路。
注意:Floyd可以判负权,但是复杂度较高,与 dijkstra 算法和 spfa 算法选择使用。
时间复杂度 O(N^3)
本博客主要以知识点复习为主。
#include<bits/stdc++.h>
using namespace std;
const int Max=10; //点的数目
const int INF=1e9; //设置无穷大
int n,m; //点与边的数目
int dis[Max][Max]; //记录路径长度
int path[Max][Max]; //记录路径过程
void init() //初始化路径
{
for(int i=0; i<Max; i++)
{
for(int j=0; j<Max; j++)
{
path[i][j]=-1;
dis[i][j]=INF;
}
dis[i][i]=0;
}
}
void read() //读入数据
{
for(int i=1; i<=m; i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
dis[u][v]=min(dis[u][v],w); //重边条件下取最短
dis[v][u]=dis[u][v];
}
}
void floyd()
{
for(int k=1;k<=n;k++) //以k点为媒介,从i到j
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dis[i][k]+dis[k][j]<dis[i][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
path[i][j]=k; //记录i到j是通过k到达的
}
}
}
}
}
void output(int i,int j) //打印路径
{
if(path[i][j]==-1) //不需要中间媒介
{
printf("->%d",j);
}
else
{
output(i,path[i][j]);
output(path[i][j],j);
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=-1)
{
init();
read();
floyd();
printf("%d\n",dis[1][n]); //判断1->n的最短路以及路径
printf("1");
output(1,n);
printf("\n");
}
return 0;
}