Skip to content

Commit 090ecdb

Browse files
committed
Make Bellman-Ford 2x faster
If we have it we might as well make it fast...
1 parent 7a1aaa8 commit 090ecdb

File tree

3 files changed

+14
-12
lines changed

3 files changed

+14
-12
lines changed
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,32 @@
55
* Source: http://en.wikipedia.org/wiki/Bellman-Ford_algorithm
66
* Description: Calculates shortest paths from $s$ in a graph that might have negative edge weights.
77
* Unreachable nodes get dist = inf; nodes reachable through negative-weight cycles get dist = -inf.
8-
* Assumes $VE \cdot \max |w_i| < 2^{63}$.
8+
* Assumes $V^2 \max |w_i| < \tilde{} 2^{63}$.
99
* Time: O(EV)
1010
* Status: Tested on kattis:shortestpath3
1111
*/
1212
#pragma once
1313

1414
const ll inf = LLONG_MAX;
15-
struct Ed { int src, dest, w; };
15+
struct Ed { int a, b, w, s() { return a < b ? a : -a; }};
1616
struct Node { ll dist = inf; int prev = -1; };
1717

1818
void bellmanFord(vector<Node>& nodes, vector<Ed>& eds, int s) {
1919
nodes[s].dist = 0;
20+
sort(all(eds), [](Ed a, Ed b) { return a.s() < b.s(); });
2021

21-
rep(i,0,sz(nodes)) trav(e, eds) {
22-
Node cur = nodes[e.src], &dest = nodes[e.dest];
22+
int lim = sz(nodes) / 2 + 2; // /3+100 with shuffled vertices
23+
rep(i,0,lim) trav(ed, eds) {
24+
Node cur = nodes[ed.a], &dest = nodes[ed.b];
2325
if (abs(cur.dist) == inf) continue;
24-
ll d = cur.dist + e.w;
26+
ll d = cur.dist + ed.w;
2527
if (d < dest.dist) {
26-
dest.prev = e.src;
27-
dest.dist = (i < sz(nodes)-1 ? d : -inf);
28+
dest.prev = ed.a;
29+
dest.dist = (i < lim-1 ? d : -inf);
2830
}
2931
}
30-
rep(i,0,sz(nodes)) trav(e, eds) {
31-
if (nodes[e.src].dist == -inf)
32-
nodes[e.dest].dist = -inf;
32+
rep(i,0,lim) trav(e, eds) {
33+
if (nodes[e.a].dist == -inf)
34+
nodes[e.b].dist = -inf;
3335
}
3436
}

content/graph/FloydWarshall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
const ll inf = 1LL << 62;
1515
void floydWarshall(vector<vector<ll>>& m) {
1616
int n = sz(m);
17-
rep(i,0,n) m[i][i] = min(m[i][i], {});
17+
rep(i,0,n) m[i][i] = min(m[i][i], 0LL);
1818
rep(k,0,n) rep(i,0,n) rep(j,0,n)
1919
if (m[i][k] != inf && m[k][j] != inf) {
2020
auto newDist = max(m[i][k] + m[k][j], -inf);

content/graph/chapter.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
\chapter{Graph}
22

33
\section{Fundamentals}
4-
\kactlimport{bellmanFord.h}
4+
\kactlimport{BellmanFord.h}
55
\kactlimport{FloydWarshall.h}
66
\kactlimport{TopoSort.h}
77

0 commit comments

Comments
 (0)