求全圖的所有最短路徑-floyd算法(弗洛伊德算法)

如果需要求出每兩點之間的最短路,不必調用n次Dijkstra(邊權均爲正)或者bellman-ford(有負權)。有一個更簡單的方法可以實現——Floyd-Warshall算法,以下代碼熟記即可,即i到j的最短路徑,是i到j的直連或者通過任意k中轉的最短路徑

for(int k=0;k<n;k++)
      for(int i=0;i<n;i++)
              for(int j=0;j<n;j++)
                     d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

在調用它之前只需做一些簡單的初始化: d[i][i] = 0, 其他d值爲INT_MAX/2。注意這裏有一個潛在的問題:如果d初始值定義太大,加法d[i][k] + d[k][j]可能會溢出。

如果d初始值太小,可能會使得長度爲d的邊真的變成最短路的一部分。例如, 最多有1000條邊,每邊<1000,那麼d的初始值可以爲1000001。

在有向圖中,有時不必關心路徑的長度,而只關心每兩點間是否有通路,則可以用1和0分別表示“連通”和“不連通”。這樣,除了預處理需做少許調整外,主算法中只需把“d[i][j]=min{d[i][j], d[i][k]+d[k][j]}”改成“d[i][j]=d[i][j]||(d[i][k]&&d[k][j])”。這樣的結果稱爲有向圖的傳遞閉包(transitive closure)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章