一下都假設該有向圖(無向圖同理)有n個點,m條邊。
談及全源最短路,第乙個想到的是弗洛伊德演算法,簡單有效,因為並非本篇文章重點,所以只是把**放在這裡:
int main()
唯一要注意的就是必須要列舉轉折點。時間複雜度o(n^3)$,當n很大時不是乙個可以接受的數字。
或者跑n遍單元最短路。你可以用spfa跑,這樣的時間複雜度為\(o(n^2m)\)可以處理負邊權。
順便一提,spfa時間複雜度稀疏圖約為\(o(m*2)\),稠密圖\(o(m*inf)\)很大乙個數有dijkstra跑的話是\(o(n^2logn)\),加了堆優化,無法處理負邊權。
可以發現,以上三種情況都不是全能的,且時間複雜度不夠優。所以我們需要乙個更有效的方法。
因為dijkstra是目前時間複雜度最優的,所以用dijkstra跑是最理想的,那麼我們需要解決負邊權的問題。
第一步:新增乙個結點(結點0)向所有結點連乙個邊權為0的邊,從這個點跑一遍spfa,檢驗是否存在負環,同時得到結點0到所有點的最短路,結點u對於結點0的最短路記為\(h_u\),同時,把起點為u終點為v的邊的權值更新為\(w_+h_u-h_v\)。因為h陣列存的是關於結點0的最短路,多有一定有\(h_v\le h_u+w_\) 否則,不等號右邊一定可以更新不等號左邊,與h陣列的定義不符。所以,在做完後所有邊的權值變成了非負值,我們可以跑dijkstra。
那麼這麼做的正確性在**?
s到t的路徑中隨便取出一條 \(
Johnson全源最短路
例題 p5905 模板 johnson 全源最短路 首先考慮求全源最短路的幾種方法 好像 只有dijkstra還有希望?但負權邊處理不了真是很棘手啊。一種方法是讓每條邊都加上乙個數 x 使得邊權為正,但考慮下圖 1 到 2 的最短路應為 1 3 4 2 長度為 1 如果我們把每條邊的邊權都加上 5 ...
Johnson演算法 多源最短路演算法
請不要輕易點選標題 乙個適用於求可含負邊權的稀疏圖的多源最短路演算法 時間複雜度 o n cdot m cdot log m n cdot m 空間複雜度 o n m 該演算法綜合利用了dijkstra演算法和bellman ford演算法 不要慌,雖然有負邊但dijkstra可以跑 在開始講解之前...
最短路 Johnson 演算法
這個演算法可以用於處理稀疏圖,帶有負權的任意兩點間的最短路問題 如果點數 但是dij中不能存在負的邊權,所以我們要考慮一種轉化邊權的方法 可以通過類似差分約束的方法來重構邊權 對一條邊 u,v 他們的權值為e dis i 表示1 i的最短路 我們可以得到dis v dis u e 因此就可以把變成d...