Johnson 演算法求全源最短路學習筆記

2022-05-07 01:00:10 字數 1812 閱讀 1940

johnson 和 floyd 一樣,是一種能求出無負環圖上任意兩點間最短路徑的演算法。該演算法在 1977 年由 donald b. johnson 提出。

任意兩點最短路可以用 floyd 演算法解決,時間複雜度 \(o(n ^ 3)\);

在沒有負權邊時,可以跑 \(n\) 次 dijkstra,時間複雜度 \(o(nm \log_2 n)\),在稀疏圖上會比較優秀;

johnson 演算法通過一些方法使有負權邊的圖也適用於第二種做法。

先把所有點加入佇列,用 spfa 進行鬆弛,每個點上的頂標記為 \(h_u\);

再將邊權設為 \(w'(u,v) = w(u,v) + h_u - h_v\);

跑 \(n\) 次 dijkstra,此時新圖上兩點間的最短路 \(dis'(u,v)\) 和原圖上最短路 \(dis(u,v)\) 滿足 \(dis(u,v) = dis'(u,v) - (h_u - h_v)\)。

時間複雜度 \(o(nm \log_2 n)\)。

證明將分為兩部分:

\(dis(u,v) = dis'(u,v) - (h_u - h_v)\);

新圖上沒有負權邊。

\((1)\):

設 \(p_1, p_k\) 間的一條路徑為 \(p_1, p_2 , p_3 \dots , p_, p_k\)。

則有:\[\sum_^ w'(p_i, p_) = \sum_ ^ w(p_i, p_) + h_ - h_} = h_ - h_ + \sum_^ w(p_i, p_)

\]\((2)\):

\(h_u\) 頂標是用 spfa 鬆弛過的,所以滿足三角形不等式:

對於一條邊 \((u,v)\),一定有 \(h_u + w(u,v) \geq h_v\) ,即:\(w(u,v) + h_u - h_v \geq 0\)。

不一定是對的,沒有例題,也沒有拍過

upd:模板 luogup5905;afo,要改的太多,懶得改。

#include #include #include #include int in() 

templateinline void chk_min(t &_, t __)

templateinline void chk_max(t &_, t __)

const int n = 1e3 + 5, mod = 998244353;

inline void add(int _, int __)

struct edge e[n << 1];

int ecnt = 1, head[n];

int n, m;

int h[n], dis[n][n];

inline void jb(const int u, const int v, const int w) , head[u] = ecnt;

}void spfa() }}

}void dijkstra(const int s, int *d) }}

for (int i = 0; i <= n; ++i)

d[i] -= h[s] - h[i];

}int main()

spfa();

for (int i = 1; i <= n; ++i)

dijkstra(i, dis[i]);

int res = 0;

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j)

add(res, dis[i][j]);

printf("%d\n", res);

return 0;

}

Johnson演算法 多源最短路演算法

請不要輕易點選標題 乙個適用於求可含負邊權的稀疏圖的多源最短路演算法 時間複雜度 o n cdot m cdot log m n cdot m 空間複雜度 o n m 該演算法綜合利用了dijkstra演算法和bellman ford演算法 不要慌,雖然有負邊但dijkstra可以跑 在開始講解之前...

Johnson全源最短路

例題 p5905 模板 johnson 全源最短路 首先考慮求全源最短路的幾種方法 好像 只有dijkstra還有希望?但負權邊處理不了真是很棘手啊。一種方法是讓每條邊都加上乙個數 x 使得邊權為正,但考慮下圖 1 到 2 的最短路應為 1 3 4 2 長度為 1 如果我們把每條邊的邊權都加上 5 ...

johnson全源最短路

一下都假設該有向圖 無向圖同理 有n個點,m條邊。談及全源最短路,第乙個想到的是弗洛伊德演算法,簡單有效,因為並非本篇文章重點,所以只是把 放在這裡 int main 唯一要注意的就是必須要列舉轉折點。時間複雜度o n 3 當n很大時不是乙個可以接受的數字。或者跑n遍單元最短路。你可以用spfa跑,...