floyd算法:可以有負權邊,但不能有負權回路


Floyd求最短路

查看題干,可以發現數據有以下特點,這也說明了folyd算法適用條件。
圖中可能存在重邊和自環,邊權可能為負數。數據保證圖中不存在負權回路。

一、代碼模板

void floyd(){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }
}

1.1首先介紹為什么把k放最外層

測試數據如下:x,y,z代表着x點->y點 距離= 1

1 10 4 //點1到點10距離為4
10 9 2
9 7 3
...

假設1-7的最短路徑為:1-10-9-7
d[1][9] = d[1][10] + d[10][7] = d[1][9]+d[9][7]
如果我們把k放最里,會發現當我們要求1-7的最小距離的時候,只能遍歷
1-1-7,1-2-7,1-3-7,... ,1-n-7
會發現我們還沒有遍歷1-k-10,1-k-9,而當我們遍歷到1-k-9(或1-k-10)的時候我們又沒法更新1-7的距離,

1.2 我們再來介紹一下為什么可以處理負邊

floyd可以處理負邊的原因很簡單,因為我們是采用暴力枚舉的方法,每個邊僅算一次,但是當產生負權回路的時候就出問題了。

1.3 當處理負權回路的時候產生的問題

測試數據如下:

1 2 -5
2 3 -3
3 1 -6

會發現1-3的距離變成了-22。
那么這個結果是怎么出現的呢?
1-k-3的結果產生來自三個地方:
1-1-3
1-2-3
1-3-3
拿1-3-3舉例發現:1-3來自於1-2-3 = -8
3-3來自於3-1-3=INF,3-2-3=-14,當然當k=3,i=1,j=3還沒有遍歷到3-3-3
所以最短為-14-8=-22

二、floyd的應用

  • 求最短路徑
  • 傳遞閉包
  • 找最小環
  • 恰好經過k條邊的最短路(倍增)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM