use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Add;
pub fn floyd_warshall<T, W>(nodes: &[T], edges: &[(T, T, W)]) -> HashMap<(T, T), W>
where
T: Eq + Hash + Clone,
W: Copy + Ord + Default + Add<Output = W> + PartialOrd,
{
let mut dist = HashMap::new();
let inf = W::default() + W::default() + W::default() + W::default() + W::default();
for u in nodes {
for v in nodes {
if u == v {
dist.insert((u.clone(), v.clone()), W::default());
} else {
dist.insert((u.clone(), v.clone()), inf);
}
}
}
for (u, v, w) in edges {
dist.insert((u.clone(), v.clone()), *w);
}
for k in nodes {
for i in nodes {
for j in nodes {
let ij = dist[&(i.clone(), j.clone())];
let ik = dist[&(i.clone(), k.clone())];
let kj = dist[&(k.clone(), j.clone())];
if ik + kj < ij {
dist.insert((i.clone(), j.clone()), ik + kj);
}
}
}
}
dist
}