use indexed_priority_queue::DefaultMapIPQ;
#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
pub struct Distance(usize);
impl Default for Distance {
fn default() -> Self {
Distance(usize::MAX)
}
}
pub fn main() {
let graph = vec![
vec![(1, 2), (2, 6)],
vec![(0, 2), (3, 5)],
vec![(0, 6), (3, 8)],
vec![(2, 8), (1, 5), (4, 10), (5, 15)],
vec![(3, 10), (6, 2)],
vec![(3, 15), (6, 6)],
vec![(4, 2), (5, 6)],
];
let (start, end) = (0, 6);
let mut queue = DefaultMapIPQ::default();
queue.push(start, Distance(0));
while let Some(node) = queue.pop() {
let node_best_distance = queue.get_priority(node).unwrap().0;
if node == end {
assert_eq!(node_best_distance, 19);
return;
}
for (neighbor, distance_to_neighbor) in &graph[node] {
let mut neighbor_best_distance = queue.update_down(*neighbor);
let alternative_distance = node_best_distance + *distance_to_neighbor;
if alternative_distance < neighbor_best_distance.0 {
*neighbor_best_distance = Distance(alternative_distance);
drop(neighbor_best_distance);
queue.restore_index(*neighbor);
}
}
}
unreachable!();
}