competitive_programming_rs/graph/
strongly_connected_components.rs1pub mod strongly_connected_components {
2 use std::collections::VecDeque;
3
4 pub fn decompose(graph: &[Vec<usize>]) -> Vec<usize> {
5 let mut vs = Vec::new();
6 let num_v = graph.len();
7 let mut cmp = vec![0; num_v];
8
9 let mut reverse_graph = vec![vec![]; num_v];
10
11 for (i, edges) in graph.iter().enumerate() {
12 for &v in edges.iter() {
13 reverse_graph[v].push(i);
14 }
15 }
16 let mut used = vec![false; num_v];
17
18 let mut stack = VecDeque::new();
19 let mut added = vec![false; num_v];
20 for i in 0..num_v {
21 if used[i] {
22 continue;
23 }
24 stack.push_front(i);
25 while let Some(v) = stack.pop_front() {
26 stack.push_front(v);
27 used[v] = true;
28 let mut pushed = false;
29 for &u in graph[v].iter().rev() {
30 if !used[u] {
31 stack.push_front(u);
32 pushed = true;
33 }
34 }
35 if !pushed {
36 stack.pop_front();
37 if !added[v] {
38 vs.push(v);
39 added[v] = true;
40 }
41 }
42 }
43 }
44
45 used = vec![false; num_v];
46 let mut k = 0;
47 vs.reverse();
48 for &i in vs.iter() {
49 if used[i] {
50 continue;
51 }
52 stack.push_front(i);
53 used[i] = true;
54 cmp[i] = k;
55 while let Some(v) = stack.pop_front() {
56 stack.push_front(v);
57 let mut pushed = false;
58 for &u in reverse_graph[v].iter() {
59 if used[u] {
60 continue;
61 }
62 used[u] = true;
63 cmp[u] = k;
64 stack.push_front(u);
65 pushed = true;
66 }
67 if !pushed {
68 stack.pop_front();
69 }
70 }
71 k += 1;
72 }
73
74 cmp
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use crate::utils::test_helper::Tester;
82
83 #[test]
84 fn solve_grl_3_c() {
85 let tester = Tester::new("./assets/GRL_3_C/in/", "./assets/GRL_3_C/out/");
86 tester.test_solution(|sc| {
87 let v: usize = sc.read();
88 let e: usize = sc.read();
89 let mut graph = vec![vec![]; v];
90 for _ in 0..e {
91 let s: usize = sc.read();
92 let t: usize = sc.read();
93 graph[s].push(t);
94 }
95
96 let cmp = strongly_connected_components::decompose(&graph);
97 let q: usize = sc.read();
98 for _ in 0..q {
99 let u: usize = sc.read();
100 let v: usize = sc.read();
101
102 if cmp[u] == cmp[v] {
103 sc.write("1\n");
104 } else {
105 sc.write("0\n");
106 }
107 }
108 });
109 }
110}