use std::collections::{BinaryHeap, HashMap};
use std::cmp::Ordering;
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
cost: usize,
position: char,
}
impl Ord for State {
fn cmp(&self, other: &Self) -> Ordering {
other.cost.cmp(&self.cost)
}
}
impl PartialOrd for State {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
fn dijkstra(graph: &HashMap<char, Vec<(char, usize)>>, start: char) -> HashMap<char, usize> {
let mut dist: HashMap<char, usize> = HashMap::new();
let mut heap = BinaryHeap::new();
for &node in graph.keys() {
dist.insert(node, usize::MAX);
}
dist.insert(start, 0);
heap.push(State { cost: 0, position: start });
while let Some(State { cost, position }) = heap.pop() {
if cost > *dist.get(&position).unwrap() {
continue;
}
if let Some(neighbors) = graph.get(&position) {
for &(neighbor, weight) in neighbors {
let next = State { cost: cost + weight, position: neighbor };
if next.cost < *dist.get(&neighbor).unwrap_or(&usize::MAX) {
dist.insert(neighbor, next.cost);
heap.push(next);
}
}
}
}
dist
}
fn main() {
let mut graph: HashMap<char, Vec<(char, usize)>> = HashMap::new();
graph.insert('A', vec![('B', 1), ('C', 2)]);
graph.insert('B', vec![('A', 1), ('C', 3)]);
graph.insert('C', vec![('A', 2), ('B', 3)]);
let distances = dijkstra(&graph, 'A');
for node in ['A', 'B', 'C'] {
let dist = distances.get(&node).unwrap_or(&usize::MAX);
if *dist == usize::MAX {
println!("Distance from A to {}: unreachable", node);
} else {
println!("Distance from A to {}: {}", node, dist);
}
}
}
Set distance to start node as zero
heap.push(State { cost: 0, position: start });
Add start node to priority queue with cost zero
while let Some(State { cost, position }) = heap.pop() {
Process nodes in order of smallest current cost
if cost > *dist.get(&position).unwrap() { continue; }
Skip if we already found a shorter path to this node
for &(neighbor, weight) in neighbors {
Check all neighbors of current node
if next.cost < *dist.get(&neighbor).unwrap_or(&usize::MAX) {
If new path to neighbor is shorter, update distance and queue
Distance from A to A: 0
Distance from A to B: 1
Distance from A to C: 2