最簡單的最短路徑是求中轉次數最少的路徑,而不考慮每條邊的權值。而在實際問題中,路徑長度的度量就不再是路徑上的邊數,而是路徑上所有邊的權值之和。
在有向網中,習慣上稱路徑的第乙個頂點為源點(source),最後乙個頂點為終點(destination)。
下面主要討論兩種最常見的最短路徑問題:
一、從某個源點到其餘頂點的最短路徑;
二、求每一對頂點之間的最短路徑。
迪傑斯特拉(dijkstra)演算法用於求解第一種問題,時間複雜度為o(n²);弗洛伊德(floyd)演算法用於求解第二種問題,時間複雜度為o(n³)。
從實現形式上來說,弗洛伊德演算法比迪傑斯特拉演算法更為簡潔。
求解每一對頂點之間的最短路徑有兩種方法:
一種是n次呼叫迪傑斯特拉演算法;
另一種是採用下面介紹的弗洛伊德演算法。
兩種演算法的時間複雜度均為o(n³),但弗洛伊德演算法的形式更為簡潔。
《邏輯思路》
(1)如果說迪傑斯特拉演算法是乙個「加邊」的過程,那麼弗洛伊德演算法就是乙個「加點」的過程;
(2)先確定兩個目標頂點,源點為vs,終點為ve;
(3)若vs和ve之間存在弧,初始化為arcs[vs-1][ve-1](編號),反之置為∞;
(4)依次判斷剩餘頂點vi,若在兩個頂點間插入vi後,使得+小於,則置換為vs和ve間的最短路徑;
(5)直至所有剩餘頂點判斷完畢,最短路徑確定;
(6)其餘的每一對頂點都重複上述過程。
《實現思路》——以鄰接矩陣為儲存結構的有向網
(1)該演算法的核心思想是設定了兩個二維輔助陣列:
1. 二維陣列path:行表示頂點vi的直接前驅,列表示頂點vi;
2. 二維陣列d]:記錄vs和ve間的最短路徑。
(2)弗洛伊德演算法的**思路比較清晰,插入、比較、更新。
void shortestpath_floyd(amgraph g)
/*---------初始化結束--------*/
for(int vi = 1; vi <= g.vexnum; vi++) /*插入點vi*/
for(int vs = 1; vs <= g.vexnum; vs++) /*源點vs*/
for(int ve = 1; ve <= g.vexnum; ve++) /*終點ve*/
}}
最短路徑之弗洛伊德
floyd演算法是大二到大三期間集訓時候才算真正接觸的,或許只有前一段時間dp的積累現在才算是真正理解 這個演算法需要充分理解dp的滾動陣列思想才能算是真正的掌握 floyd演算法又稱為插點法 演算法的目標是要求圖中所有兩個點的最短距離,就用dis i j 來表示 但是dis i 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...