圖論之最短路徑 弗洛伊德演算法(Floyd)多源最短

來源:互聯網
上載者:User
圖論之最短路徑 弗洛伊德演算法(Floyd)多源最短

一:

該演算法解決的問題是對於一個圖,對該圖的沒一對頂點vi != vj,要求求出vi與vj之間的最短路徑和最短路徑長度。

 

二:演算法思想

正如我們所知道的,Floyd演算法用於求最短路徑。Floyd演算法可以說是Warshall演算法的擴充,三個for迴圈就可以解決問題,所以它的時間複雜度為O(n^3)。

Floyd演算法的基本思想如下:從任意節點A到任意節點B的最短路徑不外乎2種可能,1是直接從a到b,2是從a經過若干個節點x到b。所以,我們假設A[a][b]為節點a到節點b的最短路徑的距離,對於每一個節點x,我們檢查A[a][x] + A[x][b] < A[a][b]是否成立,如果成立,證明從a到x再到b的路徑比a直接到b的路徑短,我們便設定A[a][b]=A[a][x]+A[x][b],這樣一來,當我們遍曆完所有節點x,A[a][b]中記錄的便是a到b的最短路徑的距離。

接下來都是一段代碼更簡明闡述:

 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];
    }
   }
  }
 }

但是這裡我們要注意迴圈的嵌套順序,如果把檢查所有節點X放在最內層,那麼結果將是不正確的,為什麼呢?因為這樣便過早的把i到j的最短路徑確定下來了,而當後面存在更短的路徑時,已經不再會更新了。

因此上段代碼的迴圈嵌套才是正確的

 

三:演算法的實現

在實現時,需要兩個數組:

1:數組A:使用同一個數組A[i][j]開存放一系列的當前的A[i][j],初始時,A[i][j]=Edge[i][j],演算法結束時A[i][j]就是vi與vj的最短路徑長度

2:path數組:path[i][j]是從vi到vj的最短路徑上頂點vj的前一個頂點的序號,主要用於路徑的列印

    

 

四:具體代碼

1:

void 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)
    path[i][j]=i;//i到j有路徑
   else
    path[i][j]=-1;//i到j無路徑
  }
 }
 //從A(-1)遞推到A(0)...A(n-1)
 //或者理解成依次將v0,v1.....v(n-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];
    }
   }
  }
 }
}

2:主函數的情況

 

 

int main()
{
 int i,j;
 int u,v,w;
 cin>>n;
 for(i=0;i<n;i++)//處理接接矩陣
 {
  for(j=0;j<n;j++)
  {
   Edge[i][j]=INF;
  }
 }
 for(i=0;i<n;i++)//方陣A的要求
 {
  Edge[i][i]=0;
 }
 while(1)
 {
  cin>>u>>v>>w;
  if(u==-1&&v==-1&&w==-1)
   break;
  Edge[u][v]=w;
 }
 Floyd();
 int shortest[MAXN];//從這開始就是為了列印路徑
 for(i=0;i<n;i++)
 {
  for(j=0;j<n;j++)
  {
   if(i==j)
    continue;
   cout<<i<<"=>"<<j<<'\t'<<A[i][j];
   memset(shortest,0,sizeof(shortest));
   int k=0;
   shortest[k]=j;
   while(path[i][shortest[k]]!=i)
   {
    k++;
    shortest[k]=path[i][shortest[k-1]];
   }
   k++;
   shortest[k]=i;
  }
 }
   for(int t=k;t>0;t--)
    cout<<shortest[t]<<"->";
   cout<<shortest[0]<<endl;
  
 return 0;
}

 //求指教

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.