Skip to content

Commit 9282af4

Browse files
extra functionality for dijkstra (#66)
* extra functionality for dijkstra * add example for looping over shortest path * fix --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com> Co-authored-by: Cameron Custer <73217097+cameroncuster@users.noreply.github.com>
1 parent d84de54 commit 9282af4

File tree

3 files changed

+30
-41
lines changed

3 files changed

+30
-41
lines changed

examples/graphs/dijk_aizu.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ fn main() {
1616
adj[u].push((v, w));
1717
}
1818

19-
let dist = dijk(&adj, s);
19+
let (dist, par) = dijk(&adj, s);
20+
21+
assert_eq!(par[s], None);
22+
2023
for d in dist {
2124
if d == u64::MAX {
2225
println!("INF");

examples/graphs/dijk_yosupo.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,22 @@ fn main() {
1717
adj[u].push((v, w));
1818
}
1919

20-
let dist = dijk(&adj, s);
20+
let (dist, par) = dijk(&adj, s);
21+
22+
assert_eq!(par[s], None);
2123

2224
if dist[t] == u64::MAX {
2325
println!("{}", -1);
2426
return;
2527
}
2628

27-
let mut par = vec![0; n];
28-
par[s] = s;
29-
let mut seen = vec![false; n];
30-
seen[s] = true;
31-
let mut q = std::collections::VecDeque::new();
32-
q.push_back(s);
33-
while let Some(u) = q.pop_front() {
34-
for &(v, w) in &adj[u] {
35-
if seen[v] || dist[u] + w != dist[v] {
36-
continue;
37-
}
38-
par[v] = u;
39-
seen[v] = true;
40-
q.push_back(v);
41-
}
42-
}
43-
4429
let mut path = vec![];
4530
let mut u = t;
46-
while u != s {
47-
path.push(u);
48-
u = par[u];
31+
path.push(u);
32+
while let Some(prev_u) = par[u] {
33+
path.push(prev_u);
34+
u = prev_u;
4935
}
50-
path.push(s);
5136

5237
path.reverse();
5338

src/graphs/dijk.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,41 @@
44
/// ```
55
/// use programming_team_code_rust::graphs::dijk::dijk;
66
///
7-
/// let adj = vec![
8-
/// vec![(1, 1), (2, 4)],
9-
/// vec![(2, 2), (3, 5)],
10-
/// vec![(3, 1)],
11-
/// vec![],
12-
/// vec![(0, 7)],
13-
/// vec![(1, 3), (3, 2)],
14-
/// vec![(0, 2), (2, 3)],
15-
/// vec![(1, 2), (4, 2)],
16-
/// ];
7+
/// let mut adj = vec![vec![]; 4];
8+
/// for (u, v, w) in [(0, 1, 10), (1, 2, 100), (0, 2, 111), (2, 2, 0)] {
9+
/// adj[u].push((v, w));
10+
/// }
1711
///
18-
/// let dist = dijk(&adj, 0);
19-
/// assert_eq!(dist, vec![0, 1, 3, 4, u64::MAX, u64::MAX, u64::MAX, u64::MAX]);
12+
/// let (dist, par) = dijk(&adj, 0);
13+
/// assert_eq!(dist, [0, 10, 110, u64::MAX]);
14+
/// assert_eq!(par, [None, Some(0), Some(1), None]);
15+
///
16+
/// let mut u = 2; // loop over shortest path in reverse
17+
/// while let Some(prev) = par[u] {
18+
/// u = prev;
19+
/// }
2020
/// ```
2121
///
2222
/// # Complexity
2323
/// - V: number of vertices
2424
/// - E: number of edges
2525
/// - Time: O(V + E log E)
2626
/// - Space: O(V + E)
27-
pub fn dijk(adj: &[Vec<(usize, u64)>], s: usize) -> Vec<u64> {
27+
pub fn dijk(adj: &[Vec<(usize, u64)>], s: usize) -> (Vec<u64>, Vec<Option<usize>>) {
2828
use std::cmp::Reverse;
2929
let n = adj.len();
3030
let mut dist = vec![u64::MAX; n];
31+
let mut par = vec![None; n];
3132
let mut q = std::collections::BinaryHeap::new();
32-
q.push(Reverse((0, s)));
33-
while let Some(Reverse((d, u))) = q.pop() {
33+
q.push(Reverse((0, s, None)));
34+
while let Some(Reverse((d, u, p))) = q.pop() {
3435
if dist[u] <= d {
3536
continue;
3637
}
37-
dist[u] = d;
38+
(dist[u], par[u]) = (d, p);
3839
for &(v, w) in &adj[u] {
39-
q.push(Reverse((dist[u] + w, v)));
40+
q.push(Reverse((dist[u] + w, v, Some(u))));
4041
}
4142
}
42-
dist
43+
(dist, par)
4344
}

0 commit comments

Comments
 (0)