Dijkstra算法是解决单源最短路径的问题,就是某个点到其余各个点的最短路径,Floyd算法是解决任意两点间最短路径问题的。
算法的大致流程如下:
设置两个二维矩阵A和path,A记录任意两个顶点最短路径长度,path记录当前两顶点最短路径上要经过的中间节点。
n个顶点,从0到n-1,每次以i为中间节点进行检测,检测所有顶点对(j,k),如果A[j][k]>A[j][i]+A[i][j],则令A[j][k]=A[j][i]+A[i][j],令path[j][k]=i。
依次检测完所有0~n-1的顶点,算法结束。最终的结果存储在A和path矩阵中。
1 #include<cstdio> 2 #define MAXSIZE 100 3 #define INF 99999 4 int A[MAXSIZE][MAXSIZE]; 5 int G[MAXSIZE][MAXSIZE]; 6 int path[MAXSIZE][MAXSIZE]; 7 void init(int n) 8 { 9 for(int i=0; i<n; ++i) 10 { 11 for(int j=0; j<n; ++j) 12 { 13 path[i][j]=-1; 14 if(i==j) 15 G[i][j]=A[i][j]=0; 16 else 17 G[i][j]=A[i][j]=INF; 18 } 19 } 20 } 21 void create(int e) 22 { 23 int a,b,val; 24 for(int i=0; i<e; ++i) 25 { 26 scanf("%d%d%d",&a,&b,&val); 27 A[a][b]=val; 28 G[a][b]=val; 29 } 30 for(int i=0; i<4; ++i) 31 { 32 for(int j=0; j<4; ++j) 33 { 34 printf("%d ",G[i][j]); 35 } 36 printf(" "); 37 } 38 printf("******************************* "); 39 } 40 void Floyd(int n) 41 { 42 for(int i=0; i<n; ++i) 43 { 44 for(int j=0; j<n; ++j) 45 { 46 for(int k=0; k<n; ++k) 47 { 48 if(j==k) 49 continue; 50 if(A[j][k]>A[j][i]+A[i][k]) 51 { 52 A[j][k]=A[j][i]+A[i][k]; 53 path[j][k]=i; 54 } 55 } 56 } 57 } 58 } 59 void print(int n) 60 { 61 for(int i=0; i<n; ++i) 62 { 63 for(int j=0; j<n; ++j) 64 { 65 printf("%d ",A[i][j]); 66 } 67 printf(" "); 68 } 69 printf("******************************* "); 70 for(int i=0; i<n; ++i) 71 { 72 for(int j=0; j<n; ++j) 73 { 74 printf("%d ",path[i][j]); 75 } 76 printf(" "); 77 } 78 } 79 void printPath(int u,int v) 80 { 81 if(path[u][v]==-1) 82 printf("%d->",u); 83 else 84 { 85 int mid = path[u][v]; 86 printPath(u,mid); 87 printPath(mid,v); 88 } 89 } 90 int main() 91 { 92 int n,e; 93 scanf("%d%d",&n,&e); 94 init(n); 95 create(e); 96 Floyd(n); 97 print(n); 98 int u,v; 99 scanf("%d%d",&u,&v); 100 printPath(u,v); 101 printf("%d",v); 102 return 0; 103 }
算法的时间复杂度为O(n3)。
例如,我们以上图所示的图进行计算,第一部分为图的邻接矩阵,第二部分为求得的A,第三部分为求得的path。
我们要求1到0的最短路径。
- path[1][0]=3,所以从1到0最短路要经过3,以3为起点
- path[3][0]=2,所以从3到1最短路要经过2,以2为起点
- path[2][0]=-1,所以,从顶点2有直接到0的边,结束
所以求最短路要用到递归,分别处理前后两段路径。