1use std::cmp::Reverse;
2use std::collections::{BTreeMap, BinaryHeap};
3use std::ops::Add;
4
5type Graph<V, E> = BTreeMap<V, BTreeMap<V, E>>;
6
7fn add_edge<V: Ord + Copy, E: Ord + Add + Copy>(graph: &mut Graph<V, E>, v1: V, v2: V, c: E) {
8 graph.entry(v1).or_insert_with(BTreeMap::new).insert(v2, c);
9 graph.entry(v2).or_insert_with(BTreeMap::new).insert(v1, c);
10}
11
12pub fn prim<V: Ord + Copy + std::fmt::Debug, E: Ord + Add + Copy + std::fmt::Debug>(
14 graph: &Graph<V, E>,
15) -> Graph<V, E> {
16 match graph.keys().next() {
17 Some(v) => prim_with_start(graph, *v),
18 None => BTreeMap::new(),
19 }
20}
21
22pub fn prim_with_start<V: Ord + Copy, E: Ord + Add + Copy>(
25 graph: &Graph<V, E>,
26 start: V,
27) -> Graph<V, E> {
28 let mut mst: Graph<V, E> = Graph::new();
30 let mut prio = BinaryHeap::new();
33
34 mst.insert(start, BTreeMap::new());
35
36 for (v, c) in &graph[&start] {
37 prio.push(Reverse((*c, v, start)));
39 }
40
41 while let Some(Reverse((dist, t, prev))) = prio.pop() {
42 if mst.contains_key(t) {
44 continue;
45 }
46
47 add_edge(&mut mst, prev, *t, dist);
49
50 for (v, c) in &graph[t] {
51 if !mst.contains_key(v) {
52 prio.push(Reverse((*c, v, *t)));
53 }
54 }
55 }
56
57 mst
58}
59
60#[cfg(test)]
61mod tests {
62 use super::{add_edge, prim, Graph};
63 use std::collections::BTreeMap;
64
65 #[test]
66 fn empty() {
67 assert_eq!(prim::<usize, usize>(&BTreeMap::new()), BTreeMap::new());
68 }
69
70 #[test]
71 fn single_vertex() {
72 let mut graph: Graph<usize, usize> = BTreeMap::new();
73 graph.insert(42, BTreeMap::new());
74
75 assert_eq!(prim(&graph), graph);
76 }
77
78 #[test]
79 fn single_edge() {
80 let mut graph = BTreeMap::new();
81
82 add_edge(&mut graph, 42, 666, 12);
83
84 assert_eq!(prim(&graph), graph);
85 }
86
87 #[test]
88 fn tree_1() {
89 let mut graph = BTreeMap::new();
90
91 add_edge(&mut graph, 0, 1, 10);
92 add_edge(&mut graph, 0, 2, 11);
93 add_edge(&mut graph, 2, 3, 12);
94 add_edge(&mut graph, 2, 4, 13);
95 add_edge(&mut graph, 1, 5, 14);
96 add_edge(&mut graph, 1, 6, 15);
97 add_edge(&mut graph, 3, 7, 16);
98
99 assert_eq!(prim(&graph), graph);
100 }
101
102 #[test]
103 fn tree_2() {
104 let mut graph = BTreeMap::new();
105
106 add_edge(&mut graph, 1, 2, 11);
107 add_edge(&mut graph, 2, 3, 12);
108 add_edge(&mut graph, 2, 4, 13);
109 add_edge(&mut graph, 4, 5, 14);
110 add_edge(&mut graph, 4, 6, 15);
111 add_edge(&mut graph, 6, 7, 16);
112
113 assert_eq!(prim(&graph), graph);
114 }
115
116 #[test]
117 fn tree_3() {
118 let mut graph = BTreeMap::new();
119
120 for i in 1..100 {
121 add_edge(&mut graph, i, 2 * i, i);
122 add_edge(&mut graph, i, 2 * i + 1, -i);
123 }
124
125 assert_eq!(prim(&graph), graph);
126 }
127
128 #[test]
129 fn graph_1() {
130 let mut graph = BTreeMap::new();
131 add_edge(&mut graph, 'a', 'b', 6);
132 add_edge(&mut graph, 'a', 'c', 7);
133 add_edge(&mut graph, 'a', 'e', 2);
134 add_edge(&mut graph, 'a', 'f', 3);
135 add_edge(&mut graph, 'b', 'c', 5);
136 add_edge(&mut graph, 'c', 'e', 5);
137 add_edge(&mut graph, 'd', 'e', 4);
138 add_edge(&mut graph, 'd', 'f', 1);
139 add_edge(&mut graph, 'e', 'f', 2);
140
141 let mut ans = BTreeMap::new();
142 add_edge(&mut ans, 'd', 'f', 1);
143 add_edge(&mut ans, 'e', 'f', 2);
144 add_edge(&mut ans, 'a', 'e', 2);
145 add_edge(&mut ans, 'b', 'c', 5);
146 add_edge(&mut ans, 'c', 'e', 5);
147
148 assert_eq!(prim(&graph), ans);
149 }
150
151 #[test]
152 fn graph_2() {
153 let mut graph = BTreeMap::new();
154 add_edge(&mut graph, 1, 2, 6);
155 add_edge(&mut graph, 1, 3, 1);
156 add_edge(&mut graph, 1, 4, 5);
157 add_edge(&mut graph, 2, 3, 5);
158 add_edge(&mut graph, 2, 5, 3);
159 add_edge(&mut graph, 3, 4, 5);
160 add_edge(&mut graph, 3, 5, 6);
161 add_edge(&mut graph, 3, 6, 4);
162 add_edge(&mut graph, 4, 6, 2);
163 add_edge(&mut graph, 5, 6, 6);
164
165 let mut ans = BTreeMap::new();
166 add_edge(&mut ans, 1, 3, 1);
167 add_edge(&mut ans, 4, 6, 2);
168 add_edge(&mut ans, 2, 5, 3);
169 add_edge(&mut ans, 2, 3, 5);
170 add_edge(&mut ans, 3, 6, 4);
171
172 assert_eq!(prim(&graph), ans);
173 }
174
175 #[test]
176 fn graph_3() {
177 let mut graph = BTreeMap::new();
178 add_edge(&mut graph, "v1", "v2", 1);
179 add_edge(&mut graph, "v1", "v3", 3);
180 add_edge(&mut graph, "v1", "v5", 6);
181 add_edge(&mut graph, "v2", "v3", 2);
182 add_edge(&mut graph, "v2", "v4", 3);
183 add_edge(&mut graph, "v2", "v5", 5);
184 add_edge(&mut graph, "v3", "v4", 5);
185 add_edge(&mut graph, "v3", "v6", 2);
186 add_edge(&mut graph, "v4", "v5", 2);
187 add_edge(&mut graph, "v4", "v6", 4);
188 add_edge(&mut graph, "v5", "v6", 1);
189
190 let mut ans = BTreeMap::new();
191 add_edge(&mut ans, "v1", "v2", 1);
192 add_edge(&mut ans, "v5", "v6", 1);
193 add_edge(&mut ans, "v2", "v3", 2);
194 add_edge(&mut ans, "v3", "v6", 2);
195 add_edge(&mut ans, "v4", "v5", 2);
196
197 assert_eq!(prim(&graph), ans);
198 }
199}