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