nekolib/algo/
exact_cover.rs1#[derive(Default)]
43pub struct ExactCover {
44 link: Vec<Node>,
45 size: Vec<usize>,
46 row: Vec<usize>,
47 col: Vec<usize>,
48}
49
50#[derive(Clone, Copy, Debug, Default)]
51struct Node {
52 left: usize,
53 right: usize,
54 up: usize,
55 down: usize,
56}
57
58impl ExactCover {
59 pub fn from_matrix(a: &Vec<Vec<usize>>) -> Self {
61 let h = a.len();
62 if h == 0 {
63 return Self::default();
64 }
65 let w = a[0].len();
66 let mut index = vec![vec![0; w]; h];
67 let mut size = vec![0; w];
68 let mut row = vec![0; w + 1];
69 let mut col = vec![0; w + 1];
70 let mut cur = w;
71 for i in 0..h {
72 for j in 0..w {
73 if a[i][j] == 0 {
74 continue;
75 }
76 cur += 1;
77 index[i][j] = cur;
78 size[j] += 1;
79 row.push(i);
80 col.push(j);
81 }
82 }
83
84 let mut link = vec![Node::default(); cur + 1];
85 link[0].right = 1;
86 link[0].left = w;
87 link[w].right = 0;
88 link[w].left = w - 1;
89 for j in 1..w {
90 link[j].right = j + 1;
91 link[j].left = j - 1;
92 }
93 for i in 0..h {
94 let first = match (0..w).find(|&j| index[i][j] != 0) {
95 Some(s) => s,
96 None => continue,
97 };
98 let mut j = first;
99 loop {
100 match (j + 1..w).find(|&nj| index[i][nj] != 0) {
101 Some(nj) => {
102 link[index[i][j]].right = index[i][nj];
103 link[index[i][nj]].left = index[i][j];
104 j = nj;
105 }
106 None => {
107 link[index[i][first]].left = index[i][j];
108 link[index[i][j]].right = index[i][first];
109 break;
110 }
111 };
112 }
113 }
114
115 for j in 0..w {
116 let first = match (0..h).find(|&i| index[i][j] != 0) {
117 Some(s) => s,
118 None => continue,
119 };
120 let mut i = first;
121 link[j + 1].down = index[i][j];
122 link[index[i][j]].up = j + 1;
123 loop {
124 match (i + 1..h).find(|&ni| index[ni][j] != 0) {
125 Some(ni) => {
126 link[index[i][j]].down = index[ni][j];
127 link[index[ni][j]].up = index[i][j];
128 i = ni;
129 }
130 None => {
131 link[j + 1].up = index[i][j];
132 link[index[i][j]].down = j + 1;
133 break;
134 }
135 }
136 }
137 }
138
139 Self { link, size, row, col }
140 }
141
142 pub fn all(mut self) -> Vec<Vec<usize>> {
144 if self.link.is_empty() || self.size.iter().any(|&x| x == 0) {
145 return vec![];
146 }
147
148 let mut res = vec![];
149 let mut cur = vec![];
150 self.dfs(&mut cur, &mut res, false);
151 res
152 }
153
154 pub fn any(mut self) -> Option<Vec<usize>> {
156 if self.link.is_empty() || self.size.iter().any(|&x| x == 0) {
157 return None;
158 }
159
160 let mut res = vec![];
161 let mut cur = vec![];
162 self.dfs(&mut cur, &mut res, true);
163 res.pop()
164 }
165
166 fn dfs(
167 &mut self,
168 cur: &mut Vec<usize>,
169 res: &mut Vec<Vec<usize>>,
170 any: bool,
171 ) {
172 if self.link[0].right == 0 {
173 res.push(cur.clone());
174 return;
175 }
176
177 let c = self.choose();
178 self.cover(c);
179 let mut r = self.link[c].down;
180 while r != c {
181 cur.push(self.row[r]);
182 let mut j = self.link[r].right;
183 while j != r {
184 self.cover(self.col[j] + 1);
185 j = self.link[j].right;
186 }
187 self.dfs(cur, res, any);
188 if any && !res.is_empty() {
189 return;
190 }
191
192 cur.pop();
193 let mut j = self.link[r].left;
194 while j != r {
195 self.uncover(self.col[j] + 1);
196 j = self.link[j].left;
197 }
198 r = self.link[r].down;
199 }
200
201 self.uncover(c);
202 }
203
204 fn choose(&self) -> usize {
205 let mut j = self.link[0].right;
206 let mut c = j;
207 let mut s = self.size[j - 1];
208 while j != 0 {
209 if self.size[j - 1] < s {
210 c = j;
211 s = self.size[j - 1];
212 }
213 j = self.link[j].right;
214 }
215 c
216 }
217
218 fn cover(&mut self, c: usize) {
219 let left = self.link[c].left;
220 let right = self.link[c].right;
221 self.link[right].left = left;
222 self.link[left].right = right;
223 let mut i = self.link[c].down;
224 while i != c {
225 let mut j = self.link[i].right;
226 while j != i {
227 let up = self.link[j].up;
228 let down = self.link[j].down;
229 self.link[down].up = up;
230 self.link[up].down = down;
231 self.size[self.col[j]] -= 1;
232 j = self.link[j].right;
233 }
234 i = self.link[i].down;
235 }
236 }
237
238 fn uncover(&mut self, c: usize) {
239 let mut i = self.link[c].up;
240 while i != c {
241 let mut j = self.link[i].left;
242 while j != i {
243 self.size[self.col[j]] += 1;
244 let down = self.link[j].down;
245 let up = self.link[j].up;
246 self.link[down].up = j;
247 self.link[up].down = j;
248 j = self.link[j].left;
249 }
250 i = self.link[i].up;
251 }
252 let right = self.link[c].right;
253 let left = self.link[c].left;
254 self.link[right].left = c;
255 self.link[left].right = c;
256 }
257}