1use std::{
59 collections::{HashMap, HashSet},
60 hash::Hash,
61};
62
63mod tarjan;
64
65pub trait Scc {
67 type Vertex: Copy + Eq + Hash;
69
70 fn vertices(&self) -> impl '_ + IntoIterator<Item = Self::Vertex>;
72
73 fn successors(&self, v: Self::Vertex) -> impl '_ + IntoIterator<Item = Self::Vertex>;
75
76 fn strongly_connected_components(&self) -> Components<Self::Vertex> {
78 tarjan::scc(self)
79 }
80}
81
82pub struct Components<V> {
84 list: Vec<Vec<V>>,
86
87 vertex_to_component: HashMap<V, usize>,
89
90 successors: Vec<HashSet<usize>>,
92}
93
94impl<V> Components<V> {
95 pub fn len(&self) -> usize {
97 self.list.len()
98 }
99
100 pub fn is_empty(&self) -> bool {
102 self.list.is_empty()
103 }
104
105 pub fn iter(&self) -> Iter<V> {
107 Iter(self.list.iter())
108 }
109
110 pub fn vertex_component_index(&self, v: &V) -> Option<usize>
112 where
113 V: Eq + Hash,
114 {
115 self.vertex_to_component.get(v).cloned()
116 }
117
118 pub fn get_by_index(&self, i: usize) -> Option<&[V]> {
120 self.list.get(i).map(Vec::as_slice)
121 }
122
123 pub fn get(&self, v: &V) -> Option<&[V]>
125 where
126 V: Eq + Hash,
127 {
128 self.get_by_index(self.vertex_component_index(v)?)
129 }
130
131 pub fn successors(&self, i: usize) -> Option<impl '_ + Iterator<Item = usize>> {
132 self.successors.get(i).map(|s| s.iter().cloned())
133 }
134
135 pub fn is_cyclic(&self, i: usize) -> bool {
136 self.successors.get(i).unwrap().contains(&i)
137 }
138
139 fn remove_indirect_successors(&self, result: &mut HashSet<usize>, i: usize) {
140 for j in self.successors(i).unwrap() {
141 result.remove(&j);
142 self.remove_indirect_successors(result, j);
143 }
144 }
145
146 pub fn direct_successors(&self, i: usize) -> Option<HashSet<usize>> {
147 let mut result: HashSet<_> = self.successors(i)?.collect();
148
149 for j in self.successors(i).unwrap() {
150 self.remove_indirect_successors(&mut result, j);
151 }
152
153 Some(result)
154 }
155
156 pub fn depths(&self) -> Vec<usize> {
161 let mut depth = vec![0; self.list.len()];
162 let mut stack: Vec<_> = depth.iter().cloned().enumerate().collect();
163
164 while let Some((i, new_depth)) = stack.pop() {
165 if depth[i] == 0 || new_depth > depth[i] {
166 depth[i] = new_depth;
167 for c in self.successors(i).unwrap() {
168 if c != i {
169 stack.push((c, new_depth + 1))
170 }
171 }
172 }
173 }
174
175 depth
176 }
177
178 pub fn predecessors(&self) -> Vec<HashSet<usize>> {
179 let mut predecessors = Vec::new();
180 predecessors.resize_with(self.list.len(), HashSet::default);
181
182 for (i, successors) in self.successors.iter().enumerate() {
183 for &j in successors {
184 predecessors[j].insert(i);
185 }
186 }
187
188 predecessors
189 }
190
191 pub fn order_by_depth(&self) -> Vec<usize> {
196 let depth = self.depths();
197 let mut ordered_components: Vec<_> = (0..self.list.len()).collect();
198 ordered_components.sort_unstable_by_key(|i| depth[*i]);
199 ordered_components
200 }
201}
202
203pub struct Iter<'a, V>(std::slice::Iter<'a, Vec<V>>);
204
205impl<'a, V> Iterator for Iter<'a, V> {
206 type Item = &'a [V];
207
208 fn next(&mut self) -> Option<Self::Item> {
209 self.0.next().map(Vec::as_slice)
210 }
211}
212
213impl<'a, V> DoubleEndedIterator for Iter<'a, V> {
214 fn next_back(&mut self) -> Option<Self::Item> {
215 self.0.next_back().map(Vec::as_slice)
216 }
217}
218
219impl<'a, V> IntoIterator for &'a Components<V> {
220 type Item = &'a [V];
221 type IntoIter = Iter<'a, V>;
222
223 fn into_iter(self) -> Self::IntoIter {
224 self.iter()
225 }
226}
227
228pub fn depths(predecessors: &[HashSet<usize>]) -> Vec<usize> {
233 let mut depth = vec![0; predecessors.len()];
234 let mut stack: Vec<_> = depth.iter().cloned().enumerate().collect();
235
236 while let Some((i, new_depth)) = stack.pop() {
237 if depth[i] == 0 || new_depth > depth[i] {
238 depth[i] = new_depth;
239 for &c in &predecessors[i] {
240 if c != i {
241 stack.push((c, new_depth + 1))
242 }
243 }
244 }
245 }
246
247 depth
248}
249
250impl Scc for Vec<HashSet<usize>> {
251 type Vertex = usize;
252
253 fn vertices(&self) -> impl '_ + IntoIterator<Item = Self::Vertex> {
254 0..self.len()
255 }
256
257 fn successors(&self, v: Self::Vertex) -> impl '_ + IntoIterator<Item = Self::Vertex> {
258 self[v].iter().copied()
259 }
260}
261
262impl<T: Copy + Eq + Hash> Scc for HashMap<T, HashSet<T>> {
263 type Vertex = T;
264
265 fn vertices(&self) -> impl '_ + IntoIterator<Item = Self::Vertex> {
266 self.keys().copied()
267 }
268
269 fn successors(&self, v: Self::Vertex) -> impl '_ + IntoIterator<Item = Self::Vertex> {
270 self[&v].iter().copied()
271 }
272}