1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::{collections::HashSet, vec};
use std::fmt::Debug;
use crate::priority_queue::PriorityQueue;
#[derive(Debug)]
pub struct Dijkstra {
adjacent_list: Vec<Vec<(usize, usize)>>,
num_nodes: usize,
}
impl Dijkstra {
pub fn new(num_nodes: usize, edges: Vec<(usize, usize, usize)>) -> Self {
let mut adjacent_list = vec![Vec::new(); num_nodes];
for edge in edges {
let source = edge.0 - 1;
let target = edge.1 - 1;
adjacent_list[source].push((target, edge.2));
}
Dijkstra {
adjacent_list,
num_nodes,
}
}
pub fn shortest_path(&self, node: usize) -> Option<(usize, Vec<usize>)> {
let mut distances = vec![usize::MAX; self.num_nodes];
distances[node-1] = 0;
let distances_ptr = distances.as_mut_ptr();
let mut heap = PriorityQueue::new(|a: &usize,b:&usize| distances.get(*a).cloned() < distances.get(*b).cloned());
let mut seens = HashSet::new();
let mut visit = Vec::new();
heap.push(node-1);
while !heap.is_empty() {
let vertex = heap.pop().unwrap();
if !seens.contains(&vertex) {
visit.push(vertex);
seens.insert(vertex);
let adjacent = &self.adjacent_list[vertex];
for pair in adjacent {
let neighbor_vertex = pair.0;
let weight = pair.1;
if distances[vertex] + weight < distances[neighbor_vertex] {
unsafe {
*distances_ptr.add(neighbor_vertex) = distances[vertex] + weight;
}
heap.push(neighbor_vertex);
}
}
}
}
distances.sort();
let max = distances.pop().unwrap();
if max < usize::MAX {
return Some((max, visit));
}
None
}
}
#[cfg(test)]
mod tests {
use std::path;
use super::*;
#[test]
fn test_dijkstra() {
let times = vec![
(1, 2, 9), (1, 4, 2), (2, 5, 1), (4, 2, 4), (4, 5, 6), (3, 2, 3), (5, 3, 7), (3, 1, 5)
];
let dijkstra = Dijkstra::new(5, times);
println!("Dijkstra: {:?}", dijkstra);
}
#[test]
fn test_shortest_path() {
let times = vec![
(1, 2, 9), (1, 4, 2), (2, 5, 1), (4, 2, 4), (4, 5, 6), (3, 2, 3), (5, 3, 7), (3, 1, 5)
];
let dijkstra = Dijkstra::new(5, times);
let (max, path) = dijkstra.shortest_path(1).unwrap();
println!("shortest path: {:?}", path);
assert_eq!(max, 14);
}
}