haar_lib/graph/
kruskal.rs1use crate::{ds::unionfind::UnionFind, graph::*};
4
5pub fn kruskal<E: EdgeTrait>(g: &Graph<Undirected, E>) -> Option<Vec<&E>>
12where
13 E::Weight: Ord + Copy,
14{
15 let n = g.len();
16 let mut edges = g
17 .nodes_iter()
18 .flat_map(|v| &v.edges)
19 .map(|e| (e, e.weight()))
20 .collect::<Vec<_>>();
21 edges.sort_unstable_by_key(|&(_, c)| c);
22
23 let mut uf = UnionFind::new(n);
24 let mut ret = vec![];
25
26 for (e, _) in edges {
27 let (u, v) = (e.from(), e.to());
28 if !uf.is_same(u, v) {
29 uf.merge(u, v);
30 ret.push(e);
31 }
32 }
33
34 (ret.len() == n - 1).then_some(ret)
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn test() {
43 let mut g = Graph::<Undirected, _>::new(6);
44 g.extend(
45 vec![
46 (0, 1, 1),
47 (0, 2, 3),
48 (1, 2, 1),
49 (1, 3, 7),
50 (2, 4, 1),
51 (1, 4, 3),
52 (3, 4, 1),
53 (3, 5, 1),
54 (4, 5, 6),
55 ]
56 .into_iter()
57 .map(|(u, v, w)| Edge::new(u, v, w, ())),
58 );
59
60 let ans = kruskal(&g).unwrap().iter().map(|e| e.weight).sum::<i32>();
61
62 assert_eq!(ans, 5);
63 }
64}