1use std::collections::HashSet;
9
10use serde::{Deserialize, Serialize};
11
12use crate::traits::BackboneStrategy;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
20struct UnionFind {
21 parent: Vec<usize>,
22 rank: Vec<usize>,
23 num_components: usize,
24}
25
26impl UnionFind {
27 fn new(n: usize) -> Self {
28 Self {
29 parent: (0..n).collect(),
30 rank: vec![0; n],
31 num_components: n,
32 }
33 }
34
35 fn ensure_capacity(&mut self, n: usize) {
36 while self.parent.len() < n {
37 let id = self.parent.len();
38 self.parent.push(id);
39 self.rank.push(0);
40 self.num_components += 1;
41 }
42 }
43
44 fn find(&mut self, mut x: usize) -> usize {
45 while self.parent[x] != x {
46 self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x];
48 }
49 x
50 }
51
52 fn union(&mut self, a: usize, b: usize) -> bool {
54 let ra = self.find(a);
55 let rb = self.find(b);
56 if ra == rb {
57 return false;
58 }
59 match self.rank[ra].cmp(&self.rank[rb]) {
61 std::cmp::Ordering::Less => self.parent[ra] = rb,
62 std::cmp::Ordering::Greater => self.parent[rb] = ra,
63 std::cmp::Ordering::Equal => {
64 self.parent[rb] = ra;
65 self.rank[ra] += 1;
66 }
67 }
68 self.num_components -= 1;
69 true
70 }
71
72 fn connected(&mut self, a: usize, b: usize) -> bool {
73 self.find(a) == self.find(b)
74 }
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct Backbone {
89 uf: UnionFind,
91 backbone_edges: HashSet<(usize, usize)>,
93 non_backbone_edges: HashSet<(usize, usize)>,
95}
96
97impl Backbone {
98 pub fn new(n: usize) -> Self {
100 Self {
101 uf: UnionFind::new(n),
102 backbone_edges: HashSet::new(),
103 non_backbone_edges: HashSet::new(),
104 }
105 }
106
107 #[inline]
109 fn edge_key(u: usize, v: usize) -> (usize, usize) {
110 if u <= v { (u, v) } else { (v, u) }
111 }
112
113 fn rebuild_uf(&mut self) {
118 let n = self.uf.parent.len();
119 self.uf = UnionFind::new(n);
120 for &(u, v) in &self.backbone_edges {
121 self.uf.union(u, v);
122 }
123 }
124}
125
126impl BackboneStrategy for Backbone {
127 fn insert_edge(&mut self, u: usize, v: usize, _weight: f64) -> bool {
128 let key = Self::edge_key(u, v);
129 self.ensure_capacity(u.max(v) + 1);
130
131 if !self.uf.connected(u, v) {
132 self.uf.union(u, v);
134 self.backbone_edges.insert(key);
135 true
136 } else {
137 self.non_backbone_edges.insert(key);
139 false
140 }
141 }
142
143 fn delete_edge(&mut self, u: usize, v: usize, _weight: f64) -> bool {
144 let key = Self::edge_key(u, v);
145
146 if self.non_backbone_edges.remove(&key) {
147 return false;
149 }
150
151 if !self.backbone_edges.remove(&key) {
152 return false;
154 }
155
156 self.rebuild_uf();
159
160 let mut replacement = None;
162 for &(a, b) in &self.non_backbone_edges {
163 if !self.uf.connected(a, b) {
164 replacement = Some((a, b));
165 break;
166 }
167 }
168
169 if let Some((a, b)) = replacement {
170 let rkey = Self::edge_key(a, b);
171 self.non_backbone_edges.remove(&rkey);
172 self.backbone_edges.insert(rkey);
173 self.uf.union(a, b);
174 }
175
176 true
177 }
178
179 fn is_backbone_edge(&self, u: usize, v: usize) -> bool {
180 self.backbone_edges.contains(&Self::edge_key(u, v))
181 }
182
183 fn num_components(&self) -> usize {
184 self.uf.num_components
185 }
186
187 fn connected(&mut self, u: usize, v: usize) -> bool {
188 if u >= self.uf.parent.len() || v >= self.uf.parent.len() {
189 return false;
190 }
191 self.uf.connected(u, v)
192 }
193
194 fn backbone_edge_count(&self) -> usize {
195 self.backbone_edges.len()
196 }
197
198 fn ensure_capacity(&mut self, n: usize) {
199 self.uf.ensure_capacity(n);
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206
207 #[test]
208 fn test_backbone_connectivity() {
209 let mut bb = Backbone::new(4);
210 assert!(bb.insert_edge(0, 1, 1.0)); assert!(bb.insert_edge(1, 2, 1.0)); assert!(bb.insert_edge(2, 3, 1.0)); assert!(!bb.insert_edge(0, 3, 1.0)); assert_eq!(bb.num_components(), 1);
217 assert_eq!(bb.backbone_edge_count(), 3);
218 assert!(bb.is_backbone_edge(0, 1));
219 assert!(!bb.is_backbone_edge(0, 3));
220 }
221
222 #[test]
223 fn test_backbone_deletion_with_replacement() {
224 let mut bb = Backbone::new(3);
225 bb.insert_edge(0, 1, 1.0); bb.insert_edge(1, 2, 1.0); bb.insert_edge(0, 2, 1.0); assert_eq!(bb.backbone_edge_count(), 2);
230
231 let modified = bb.delete_edge(0, 1, 1.0);
233 assert!(modified);
234 assert_eq!(bb.num_components(), 1);
235 assert!(bb.is_backbone_edge(0, 2));
237 }
238
239 #[test]
240 fn test_backbone_deletion_no_replacement() {
241 let mut bb = Backbone::new(3);
242 bb.insert_edge(0, 1, 1.0);
243 bb.insert_edge(1, 2, 1.0);
244
245 let modified = bb.delete_edge(0, 1, 1.0);
247 assert!(modified);
248 assert_eq!(bb.num_components(), 2);
249 }
250
251 #[test]
252 fn test_auto_grow() {
253 let mut bb = Backbone::new(0);
254 assert!(bb.insert_edge(5, 10, 1.0));
255 assert!(bb.connected(5, 10));
256 assert_eq!(bb.backbone_edge_count(), 1);
257 }
258}