dijkstra演算法
dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。
最常見的問題就是:給你一張地圖,讓你求出指定的點到其餘各定點的最短路徑。
演算法核心:每次找到離源點最近的乙個頂點,然後以該頂點為中心進行擴充套件,最終的到源點到其餘所有點的最短路徑。演算法的時間複雜度為o(n2),空間複雜度為o(n3)。
基本步驟如下:
將所有的頂點分為兩部分:已知最短路程的頂點集合p和未知最短路徑的頂點集合q。最開始,已知最短路徑的頂點集合p中只有源點和乙個頂點。這裡用book陣列來記錄哪些點在集合p中。例如對於某個頂點i,如果book[i]為1則表示這個頂點在集合p中,如果book[i]為0則表示這個頂點在集合q中。
設定源點s到自己的最短路徑為0即dis[s]=0。若存在有源點能直接到達的頂點i,則把dis[i]設為e[s][i]。同時把所有其他(源點不能直接到達的)頂點的最短路徑設為∞。
在集合q的所有頂點中選擇乙個離源點s最近的頂點u(即dis[u]最小)加入到集合p。並考察所有以點u為起點的邊,對每一條邊進行鬆弛操作。例如存在一條從u到v的邊,那麼可以通過將邊u→v新增到尾部來拓展一條從s到v的路徑,這條路徑的長度是dis[i]+e[u][v]。如果這個值比目前已知的dis[v]的值要小,我們可以用新值來替代當前dis[v]中的值。
重複第3步,如果集合q為空,演算法結束。最終dis陣列中的值就是源點到所有頂點的最短路徑。
dijkstra演算法核心**:
for (i = 1; i < n; i++)
}book[u] = 1; //將此點加入最短距離點
for (v = 0; v <= n; v++)
}}
floyd演算法
floyd(弗洛伊德)演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或負權的最短路徑問題。
最常見的問題就是:給你一張地圖,求任意兩點之間的最短路徑。
演算法核心:每次引入乙個點k來更新i到j最短距離,求出任意兩點之間的最短距離。
演算法的時間複雜度為o(n3),空間複雜度為o(n2)。
基本步驟如下:
從任意一條單邊路徑開始,所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。
對於每一對頂點u和v,看看是否存在乙個頂點w使得從u到w再到v比己知的路徑更短,如果是更新它。
對於所有的頂點,都重複上面的操作,直到遍歷所有的頂點。
floyd演算法核心**:
for (k = 1; k <= n; k++)
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (e[i][j] > e[i][k] + e[k][j]) //如果i到j城市的路徑小於從i到k再從k到j,就更新e[i][j]的值
e[i][j] = e[i][k] + e[k][j];
最短路演算法總結
1.floyd演算法 n 3複雜度 基本思想 開始設集合s的初始狀態為空,然後依次將0,1,n 1定點加入,同時用d i j 儲存從i到j,僅經過s中的定點的最短路徑,在初始時刻,d i j a i j 中間不經過任何節點,然後依次向s中插入節點,並進行如下更新 d k i j min 還可以使用乙...
最短路演算法總結
藉著usaco 3.26搞了幾天最短路。不得不說usaco真是菜鳥學習演算法的利器啊,有資料可以查錯。題上是乙個800 800的稀疏圖,需要求全源最短路 先用floyd試了一下。畢竟就三行,很好寫。時間o n3 裸交第九個點果然tle了,不過看題解有人水過了 就把邏輯語言改了一下,無向圖時間又可以優...
最短路演算法總結
顧名思義就是尋找乙個源點到其它的點的最短路,暴力的dfs或者bfs就不說了,下面講講幾種單源最短路的演算法。這個演算法的實質就是利用bfs,我們先將源點到源點的距離設定為0,到其它的距離設定為無窮大 一般0x7fffffff 然後將源點加入佇列,用隊首的點去bfs,更新它能到達且能更新的的點,然後將...