|
3 | 3 | * Date: 2015-02-23 |
4 | 4 | * License: CC0 |
5 | 5 | * Source: http://en.wikipedia.org/wiki/Bellman-Ford_algorithm |
6 | | - * Description: Calculates shortest path in a graph that might have negative edge distances. |
7 | | - * Propagates negative infinity distances (sets dist = -inf), and returns true |
8 | | - * if there is some negative cycle. Unreachable nodes get dist = inf. |
| 6 | + * Description: Calculates shortest paths from $s$ in a graph that might have negative edge weights. |
| 7 | + * Unreachable nodes get dist = inf; nodes reachable through negative-weight cycles get dist = -inf. |
| 8 | + * Assumes $VE \cdot \max |w_i| < 2^{63}$. |
9 | 9 | * Time: O(EV) |
10 | | - * Status: Untested |
| 10 | + * Status: Tested on kattis:shortestpath3 |
11 | 11 | */ |
12 | 12 | #pragma once |
13 | 13 |
|
14 | | -typedef ll T; // or whatever |
15 | | -struct Edge { int src, dest; T weight; }; |
16 | | -struct Node { T dist; int prev; }; |
17 | | -struct Graph { vector<Node> nodes; vector<Edge> edges; }; |
| 14 | +const ll inf = LLONG_MAX; |
| 15 | +struct Ed { int src, dest, w; }; |
| 16 | +struct Node { ll dist = inf; int prev = -1; }; |
18 | 17 |
|
19 | | -const T inf = numeric_limits<T>::max(); |
20 | | -bool bellmanFord2(Graph& g, int start_node) { |
21 | | - trav(n, g.nodes) { n.dist = inf; n.prev = -1; } |
22 | | - g.nodes[start_node].dist = 0; |
| 18 | +void bellmanFord(vector<Node>& nodes, vector<Ed>& eds, int s) { |
| 19 | + nodes[s].dist = 0; |
23 | 20 |
|
24 | | - rep(i,0,sz(g.nodes)) trav(e, g.edges) { |
25 | | - Node& cur = g.nodes[e.src]; |
26 | | - Node& dest = g.nodes[e.dest]; |
27 | | - if (cur.dist == inf) continue; |
28 | | - T ndist = cur.dist + (cur.dist == -inf ? 0 : e.weight); |
29 | | - if (ndist < dest.dist) { |
| 21 | + rep(i,0,sz(nodes)) trav(e, eds) { |
| 22 | + Node cur = nodes[e.src], &dest = nodes[e.dest]; |
| 23 | + if (abs(cur.dist) == inf) continue; |
| 24 | + ll d = cur.dist + e.w; |
| 25 | + if (d < dest.dist) { |
30 | 26 | dest.prev = e.src; |
31 | | - dest.dist = (i >= sz(g.nodes)-1 ? -inf : ndist); |
| 27 | + dest.dist = (i < sz(nodes)-1 ? d : -inf); |
32 | 28 | } |
33 | 29 | } |
34 | | - bool ret = 0; |
35 | | - rep(i,0,sz(g.nodes)) trav(e, g.edges) { |
36 | | - if (g.nodes[e.src].dist == -inf) |
37 | | - g.nodes[e.dest].dist = -inf, ret = 1; |
| 30 | + rep(i,0,sz(nodes)) trav(e, eds) { |
| 31 | + if (nodes[e.src].dist == -inf) |
| 32 | + nodes[e.dest].dist = -inf; |
38 | 33 | } |
39 | | - return ret; |
40 | 34 | } |
0 commit comments