求有向網中任意一對頂點之間的最短路徑 Floyd演算法
阿新 • • 發佈:2019-02-03
有向網中欲知任意一對頂點之間的最短路徑常用Floyd演算法,基本思想是任意一對頂點vi與vj,逐步在其中加入一箇中間節點v0,..,vk,...vn,若比原路徑短則更新最短路徑,經過n次比較和修正後,vi到vj的最短路徑可以求出。具體程式碼及相關注釋如下
//floyd求任意頂點間的最短路徑 #include<stdio.h> #define N 20//最大頂點數 #define INF 10000 typedef struct { int vexs[N];//頂點表 int adjMatrix[N][N];//鄰接矩陣,即邊表 int vexnum,arcnum;//頂點數和邊數 }MGraph;//圖 typedef struct{ int begin,end;//邊頂點序號 int cost;//邊上的權值 }TreeEdge;//用於儲存最小生成樹的邊表型別 //建立有向圖的鄰接矩陣儲存 void CreateMGraph(MGraph *G){ int i,j,k,x; printf("請輸入頂點數和邊數(輸入的格式為:頂點數 邊數);\n"); scanf("%d %d",&(G->vexnum),&(G->arcnum)); for(i=0;i<G->vexnum;i++)//初始化鄰接矩陣的元素 for(j=0;j<G->arcnum;j++){ G->adjMatrix[i][j]=INF; } printf("輸入%d條邊,格式:行下標 列下標 邊上的權值\n",G->arcnum); for(k=0;k<G->arcnum;k++){ scanf("%d %d %d",&i,&j,&x); G->adjMatrix[i][j]=x; } } //輸出i,j最短路徑的中間結點 void shortpath(int path[][N],int i,int j){ int k=path[i][j]; if(k){ shortpath(path,i,k); printf("%d,",k); shortpath(path,k,j); } } //求有向網中的各對頂點i和j之間的最短p[i][j]及其帶權路徑A[i][j] void Floyd(MGraph *G){ int i,j,k; int A[N][N],p[N][N]; for(i=0;i<G->vexnum;i++){//各對頂點之間初始已知路徑及距離 for(j=0;j<G->vexnum;j++){ A[i][j]=G->adjMatrix[i][j]; p[i][j]=0; } A[i][i]=0; } //通過vk修正vi到vj的最短路徑 for(k=0;k<G->vexnum;k++)//k為逐漸加入的中間結點 for(i=0;i<G->vexnum;i++){ if(A[i][k]<INF){ for(j=0;j<G->vexnum;j++){ if(A[i][k]+A[k][j]<A[i][j]){ A[i][j]=A[i][k]+A[k][j]; p[i][j]=k; } } } } printf("輸入最短路徑:\n"); for(i=0;i<G->vexnum;i++) for(j=0;j<G->vexnum;j++) if(A[i][j]==0){ if(i!=j){ printf("從%d到%d不存在路徑\n",i,j); } }else{ printf("從%d到%d的最短路徑長度為:%d\t路徑為:",i,j,A[i][j]); printf("%d,",i); shortpath(p,i,j); printf("%d\n",j); } } int main(){ MGraph *G=(MGraph *)malloc(sizeof(MGraph)); CreateMGraph(G); Floyd(G); }