|
5 | 5 | * Source: http://en.wikipedia.org/wiki/Bellman-Ford_algorithm |
6 | 6 | * Description: Calculates shortest paths from $s$ in a graph that might have negative edge weights. |
7 | 7 | * 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}$. |
9 | 9 | * Time: O(EV) |
10 | 10 | * Status: Tested on kattis:shortestpath3 |
11 | 11 | */ |
12 | 12 | #pragma once |
13 | 13 |
|
14 | 14 | 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; }}; |
16 | 16 | struct Node { ll dist = inf; int prev = -1; }; |
17 | 17 |
|
18 | 18 | void bellmanFord(vector<Node>& nodes, vector<Ed>& eds, int s) { |
19 | 19 | nodes[s].dist = 0; |
| 20 | + sort(all(eds), [](Ed a, Ed b) { return a.s() < b.s(); }); |
20 | 21 |
|
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]; |
23 | 25 | if (abs(cur.dist) == inf) continue; |
24 | | - ll d = cur.dist + e.w; |
| 26 | + ll d = cur.dist + ed.w; |
25 | 27 | 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); |
28 | 30 | } |
29 | 31 | } |
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; |
33 | 35 | } |
34 | 36 | } |
0 commit comments