On this page
article
Johnson
Sobre
funciona igual ao Floyd-Warshall
encontra o menor caminho entre todo
par de vertices e retorna 1 sse tem
ciclo negativo no grafo
O(nm log(m))
Link original: johnson.cpp
Código
vector<pair<int, ll>> g[MAX]; // {vizinho, peso}
ll d[MAX][MAX];
bool johnson(int n) {
vector<ll> h(n, 0);
for (int i = 0; i <= n; i++)
for (int v = 0; v < n; v++)
for (auto [u, w] : g[v]) if (h[u] > h[v] + w) {
if (i == n) return 1;
h[u] = h[v] + w;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) d[i][j] = LINF;
d[i][i] = 0;
priority_queue<pair<ll, int>> pq;
pq.emplace(0, i);
while (pq.size()) {
auto [ndist, v] = pq.top(); pq.pop();
if (-ndist > d[i][v]) continue;
for (auto [u, w] : g[v]) {
w += h[v] - h[u];
if (d[i][u] > d[i][v] + w) {
d[i][u] = d[i][v] + w;
pq.emplace(-d[i][u], u);
}
}
}
for (int j = 0; j < n; j++)
d[i][j] += h[j] - h[i];
}
return 0;
}