1. 程式人生 > >求有向網中任意一對頂點之間的最短路徑 Floyd演算法

求有向網中任意一對頂點之間的最短路徑 Floyd演算法

       有向網中欲知任意一對頂點之間的最短路徑常用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);
}