最短路-弗洛伊德(Floyd)算法

来源:互联网 发布:经济学书籍推荐 知乎 编辑:程序博客网 时间:2024/06/06 02:27
弗洛伊德(Floyd)算法
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);

状态转移方程

其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};
map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值应该为0,或者按照题目意思来做。
当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路。
优点:可以算出任意两个节点之间的最短距离,在这个意义上比迪克斯塔拉算法和spfa好。
缺点:时间复杂度比较高,不适合计算大量数据。(慎用)与bellman——ford算法相似允许带负权值,但不能有负权值回路


#include <iostream>#include<cstdio>#include <string>#include<string.h>#include<algorithm>#include<map>#include<queue>#include<stack>using namespace std;#define inf 0x3f3f3f3f#define maxn 8int n;int edge[maxn][maxn];//领接矩阵int a[maxn][maxn],//存放i=>j的最小值,且用于更新path[maxn][maxn];//存放到j的前一个的序号,使用前应先全置于-1void floyd(){int i,j,k;for(i=0;i<n;i++){for(j=0;j<n;j++){a[i][j]=edge[i][j];//初始化a【】【】if(i!=j&&a[i][j]<inf)//i到j有直接路径path[i][j]=i;//无直接路径else path[i][j]=-1;//无直接路径}}for(k=0;k<n;k++)//{for(i=0;i<n;i++){for(j=0;j<n;j++){if(k==i||k==j)continue;if(a[i][k]+a[k][j]<a[i][j]){a[i][j]=a[i][k]+a[k][j];path[i][j]=path[k][j];}}}}}int main(){#ifdef zsc       freopen("Text.txt","r",stdin); freopen("output.txt","w",stdout);#endif  int i,j;int u,v,w;scanf("%d",&n);for(i=0;i<n;i++){for(j=0;j<n;j++)edge[i][j]=inf;}for(i=0;i<n;i++){edge[i][i]=0;}while(1){scanf("%d%d%d",&u,&v,&w);if(u==-1) break;edge[u][v]=w;}floyd();int s[maxn];for(i=0;i<n;i++){for(j=0;j<n;j++){if(i==j) continue;cout<<i<<"=>"<<j<<"   "<<a[i][j]<<"  ";memset(s,0,sizeof(s));int k=0;s[k]=j;while(path[i][s[k]]!=i){k++;s[k]=path[i][s[k-1]];}k++;s[k]=i;for(int t=k;t>0;t--)printf("%d>",s[t]);printf("%d\n",s[0]);}}return 0;}//输入://4//0 1 1 //0 3 4//1 2 9//1 3 2//2 0 3//2 1 5//2 3 8//3 2 6//-1 -1 -1//输出://0=>1   1  0>1//0=>2   9  0>1>3>2//0=>3   3  0>1>3//1=>0   11  1>3>2>0//1=>2   8  1>3>2//1=>3   2  1>3//2=>0   3  2>0//2=>1   4  2>0>1//2=>3   6  2>0>1>3//3=>0   9  3>2>0//3=>1   10  3>2>0>1//3=>2   6  3>2////


0 0
原创粉丝点击