1use crate::graph::*;
4
5pub struct SCC {
7 groups: Vec<Vec<usize>>,
8 index: Vec<usize>,
9}
10
11impl SCC {
12 pub fn new<E: EdgeTrait>(g: &Graph<Directed, E>) -> Self {
16 let n = g.len();
17
18 let mut check = vec![false; n];
19 let mut ord = Vec::with_capacity(n);
20 for i in 0..n {
21 if !check[i] {
22 Self::dfs(g, i, &mut ord, &mut check);
23 }
24 }
25 ord.reverse();
26
27 let mut rg = vec![vec![]; n];
28 for e in g.nodes_iter().flat_map(|v| &v.edges) {
29 rg[e.to()].push(e.from());
30 }
31
32 let mut groups = vec![];
33 let mut check = vec![false; n];
34
35 let mut stack: Vec<usize> = Vec::with_capacity(n);
36
37 for u in ord {
38 if !check[u] {
39 let mut temp = vec![];
40 stack.push(u);
41 while let Some(cur) = stack.pop() {
42 check[cur] = true;
43 for &to in &rg[cur] {
44 if !check[to] {
45 stack.push(to);
46 }
47 }
48 temp.push(cur);
49 }
50 groups.push(temp);
51 }
52 }
53
54 let mut index = vec![0; n];
55 for (i, s) in groups.iter().enumerate() {
56 for &x in s {
57 index[x] = i;
58 }
59 }
60
61 Self { groups, index }
62 }
63
64 fn dfs<E: EdgeTrait>(
65 g: &Graph<Directed, E>,
66 cur: usize,
67 ord: &mut Vec<usize>,
68 check: &mut [bool],
69 ) {
70 check[cur] = true;
71 for e in g.nodes[cur].edges.iter() {
72 if !check[e.to()] {
73 Self::dfs(g, e.to(), ord, check);
74 }
75 }
76
77 ord.push(cur);
78 }
79
80 pub fn groups(&self) -> &Vec<Vec<usize>> {
82 &self.groups
83 }
84
85 pub fn index(&self) -> &Vec<usize> {
87 &self.index
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test() {
97 let mut g = Graph::<Directed, _>::new(5);
100 g.extend(
101 vec![(0, 1), (1, 0), (1, 2), (2, 4), (4, 3), (3, 2)]
102 .into_iter()
103 .map(|(u, v)| Edge::new(u, v, (), ())),
104 );
105 let scc = SCC::new(&g);
106 let scc = scc.index();
107
108 assert_eq!(scc[0], scc[1]);
109 assert_ne!(scc[0], scc[3]);
110 assert_eq!(scc[2], scc[3]);
111 assert_eq!(scc[3], scc[4]);
112 }
113}