haar_lib/ds/
rollbackable_unionfind.rs1enum History {
7 Nop,
8 Merge(usize, usize, usize),
9}
10
11pub struct RollbackableUnionFind {
13 parent: Vec<Option<usize>>,
14 size: Vec<usize>,
15 history: Vec<History>,
16}
17
18impl RollbackableUnionFind {
19 pub fn new(n: usize) -> Self {
21 Self {
22 parent: vec![None; n],
23 size: vec![1; n],
24 history: vec![],
25 }
26 }
27
28 pub fn root_of(&self, i: usize) -> usize {
30 if let Some(p) = self.parent[i] {
31 self.root_of(p)
32 } else {
33 i
34 }
35 }
36
37 pub fn is_same(&self, i: usize, j: usize) -> bool {
39 self.root_of(i) == self.root_of(j)
40 }
41
42 pub fn merge(&mut self, i: usize, j: usize) -> usize {
44 let ri = self.root_of(i);
45 let rj = self.root_of(j);
46
47 if ri == rj {
48 self.history.push(History::Nop);
49 return ri;
50 }
51
52 if self.size[ri] < self.size[rj] {
53 self.history.push(History::Merge(ri, rj, self.size[rj]));
54 self.parent[ri] = Some(rj);
55 self.size[rj] += self.size[ri];
56 rj
57 } else {
58 self.history.push(History::Merge(rj, ri, self.size[ri]));
59 self.parent[rj] = Some(ri);
60 self.size[ri] += self.size[rj];
61 ri
62 }
63 }
64
65 pub fn rollback(&mut self) -> bool {
67 match self.history.pop() {
68 Some(History::Nop) => true,
69 Some(History::Merge(c, p, s)) => {
70 self.parent[c] = None;
71 self.size[p] = s;
72 true
73 }
74 None => false,
75 }
76 }
77
78 pub fn size_of(&self, i: usize) -> usize {
80 self.size[self.root_of(i)]
81 }
82}