最短路徑之弗洛伊德

Floyd算法是大二到大三期間集訓時候纔算真正接觸的,或許只有前一段時間DP的積累現在纔算是真正理解

這個算法需要充分理解DP的滾動數組思想才能算是真正的掌握

Floyd算法又稱爲插點法

算法的目標是要求圖中所有兩個點的最短距離,就用dis[i][j]來表示

但是dis[i][j]是不夠設置爲狀態的,因爲這個狀態比較粗略,狀態之間無法轉換

這裏就加了一個很神奇的限制條件,然後形成了這個狀態:dis[i][j][k]表示從i到j的最短路,並且這條路上的點只能經過編號爲0-k這些點,所以光求出某個dis[i][j][*]還不行,必須要dis[i][j][N]纔等於 i 到 j 的最短距離。

d[i][j][k]表示從i到j途中只允許經過[0,k]這些節點時的最短距離;

這個k是代表編號,不是有k個

i到j的最短路中不經過k點時:dis[i][j][k] = dis[i][j][k-1]

經過:dis[i][j][k] = dis[i][k][k-1]+dis[k][j][k-1]

所以dis[i][j][k] = min(dis[i][j][k-1],dis[i][k][k-1]+dis[k][j][k-1]);

這裏就可以差不多有爲什麼FLOYD能求出最短路的感覺了,因爲其實它也是靠K把一個個中間點試過來的。

這樣一看就可以用滾動數組了,簡化爲dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);

 

Floyd的初始化問題:dis[i][j]若i,j有直接相連的邊則初始化爲邊權,沒有則初始化爲INF(求最小路徑時),-INF(求最大路徑時)

Floyd的路徑輸出:

一個很好的FLOYD打印路徑博客

記錄路徑肯定是得再用一個數組了,一維的肯定是不夠的,連從誰到誰都表示不出來

使用path[i][j],path[i][j]表示從i到j的最短路中,i的下一個點是誰k,這樣就可以path[i][j] = k,path[k][j]順藤摸瓜把整條路都解決了

 

 

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