Floyd-Warshall算法(Floyd-Warshallalgorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。
Floyd-Warshall算法的时间复杂度为n^3,空间复杂度为N^2。
原理
实现代码
#define MAX_VERTEX_NUM 100 //最大顶点数 #define MAX_INT 10000 //无穷大 typedef int AdjType; typedef struct{ int pi[MAX_VERTEX_NUM];//存放v到vi的一条最短路径 int end; }PathType; typedef char VType; //设顶点为字符类型 typedef struct{ VType V[MAX_VERTEX_NUM]; //顶点存储空间 AdjType A[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵 }MGraph;//邻接矩阵表示的图 //Floyd算法 //求网G(用邻接矩阵表示)中任意两点间最短路径 //D[][]是最短路径长度矩阵,path[][]最短路径标志矩阵 void Floyd(MGraph * G,int path[][MAX_VERTEX_NUM],int D[][MAX_VERTEX_NUM],int n){ int i,j,k; for(i=0;i<n;i++){//初始化 for(j=0;j<n;j++){ if(G->A[i][j]<MAX_INT){ path[i][j]=j; }else{ path[i][j]=-1; } D[i][j]=G->A[i][j]; } } for(k=0;k<n;k++){//进行n次试探 for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(D[i][j]>D[i][k]+D[k][j]){ D[i][j]=D[i][k]+D[k][j];//取小者 path[i][j]=path[i][k];//改Vi的后继 } } } } } int main(){ int i,j,k,v=0,n=6;//v为起点,n为顶点个数 MGraph G; int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点的最短路径向量 int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点最短路径长度向量 //初始化 AdjType a[MAX_VERTEX_NUM][MAX_VERTEX_NUM]={ {0,12,18,MAX_INT,17,MAX_INT}, {12,0,10,3,MAX_INT,5}, {18,10,0,MAX_INT,21,11}, {MAX_INT,3,MAX_INT,0,MAX_INT,8}, {17,MAX_INT,21,MAX_INT,0,16}, {MAX_INT,5,11,8,16,0} }; for(i=0;i<n;i++){ for(j=0;j<n;j++){ G.A[i][j]=a[i][j]; } } Floyd(&G,path,D,6); for(i=0;i<n;i++){//输出每对顶点间最短路径长度及最短路径 for(j=0;j<n;j++){ printf("V%d到V%d的最短长度:",i,j); printf("%d\t",D[i][j]);//输出Vi到Vj的最短路径长度 k=path[i][j];//取路径上Vi的后续Vk if(k==-1){ printf("There is no path between V%d and V%d\n",i,j);//路径不存在 }else{ printf("最短路径为:"); printf("(V%d",i);//输出Vi的序号i while(k!=j){//k不等于路径终点j时 printf(",V%d",k);//输出k k=path[k][j];//求路径上下一顶点序号 } printf(",V%d)\n",j);//输出路径终点序号 } printf("\n"); } } system("pause"); return 0; }