最短路徑之弗洛伊德

2021-09-27 04:45:15 字數 1048 閱讀 1184

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]順藤摸瓜把整條路都解決了

MPI之弗洛伊德最短路徑演算法

include include include for debugging include const int infinity 1000000 void read matrix int local mat,int n,int my rank,int p,mpi comm comm void pri...

弗洛伊德演算法求最短路徑

include includeusing namespace std 鄰接矩陣的型別定義 define max 10000000 define max vertex num 20 typedef struct mgraph 構造有向網的鄰接矩陣 void createdn am mgraph g,i...

最短路徑 弗洛伊德 Floyd 演算法

弗洛伊德 floyd 演算法 是解決任意兩點間的最短路徑的一種演算法 floyd演算法是乙個經典的動態規劃演算法 用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做乙個詮釋 這個詮釋正是動態規劃最富創造力的精華所在 從任意節點i到任意...