Skip to content

Commit dc64b31

Browse files
Merge branch 'master' into feature/segtree
2 parents 7f70828 + 6d1e6a7 commit dc64b31

File tree

4 files changed

+299
-0
lines changed

4 files changed

+299
-0
lines changed

src/internal_queue.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,104 @@
1+
#![allow(dead_code)]
12

3+
#[derive(Default)]
4+
pub(crate) struct SimpleQueue<T> {
5+
payload: Vec<T>,
6+
pos: usize,
7+
}
8+
9+
impl<T> SimpleQueue<T> {
10+
pub(crate) fn reserve(&mut self, n: usize) {
11+
if n > self.payload.len() {
12+
self.payload.reserve(n - self.payload.len());
13+
}
14+
}
15+
16+
pub(crate) fn size(&self) -> usize {
17+
self.payload.len() - self.pos
18+
}
19+
20+
pub(crate) fn empty(&self) -> bool {
21+
self.pos == self.payload.len()
22+
}
23+
24+
pub(crate) fn push(&mut self, t: T) {
25+
self.payload.push(t);
26+
}
27+
28+
// Do we need mutable version?
29+
pub(crate) fn front(&self) -> Option<&T> {
30+
if self.pos < self.payload.len() {
31+
Some(&self.payload[self.pos])
32+
} else {
33+
None
34+
}
35+
}
36+
37+
pub(crate) fn clear(&mut self) {
38+
self.payload.clear();
39+
self.pos = 0;
40+
}
41+
42+
pub(crate) fn pop(&mut self) -> Option<&T> {
43+
if self.pos < self.payload.len() {
44+
self.pos += 1;
45+
Some(&self.payload[self.pos - 1])
46+
} else {
47+
None
48+
}
49+
}
50+
}
51+
52+
#[cfg(test)]
53+
mod test {
54+
use crate::internal_queue::SimpleQueue;
55+
56+
#[allow(clippy::cognitive_complexity)]
57+
#[test]
58+
fn test_simple_queue() {
59+
let mut queue = SimpleQueue::default();
60+
61+
assert_eq!(queue.size(), 0);
62+
assert!(queue.empty());
63+
assert!(queue.front().is_none());
64+
assert!(queue.pop().is_none());
65+
66+
queue.push(123);
67+
68+
assert_eq!(queue.size(), 1);
69+
assert!(!queue.empty());
70+
assert_eq!(queue.front(), Some(&123));
71+
72+
queue.push(456);
73+
74+
assert_eq!(queue.size(), 2);
75+
assert!(!queue.empty());
76+
assert_eq!(queue.front(), Some(&123));
77+
78+
assert_eq!(queue.pop(), Some(&123));
79+
assert_eq!(queue.size(), 1);
80+
assert!(!queue.empty());
81+
assert_eq!(queue.front(), Some(&456));
82+
83+
queue.push(789);
84+
queue.push(789);
85+
queue.push(456);
86+
queue.push(456);
87+
88+
assert_eq!(queue.size(), 5);
89+
assert!(!queue.empty());
90+
assert_eq!(queue.front(), Some(&456));
91+
92+
assert_eq!(queue.pop(), Some(&456));
93+
assert_eq!(queue.size(), 4);
94+
assert!(!queue.empty());
95+
assert_eq!(queue.front(), Some(&789));
96+
97+
queue.clear();
98+
99+
assert_eq!(queue.size(), 0);
100+
assert!(queue.empty());
101+
assert!(queue.front().is_none());
102+
assert!(queue.pop().is_none());
103+
}
104+
}

src/internal_scc.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,134 @@
1+
pub struct Csr<E> {
2+
start: Vec<usize>,
3+
elist: Vec<E>,
4+
}
15

6+
impl<E> Csr<E>
7+
where
8+
E: Copy,
9+
{
10+
pub fn new(n: usize, edges: &[(usize, E)], init: E) -> Self {
11+
let mut csr = Csr {
12+
start: vec![0; n + 1],
13+
elist: vec![init; edges.len()],
14+
};
15+
for e in edges.iter() {
16+
csr.start[e.0 + 1] += 1;
17+
}
18+
for i in 1..=n {
19+
csr.start[i] += csr.start[i - 1];
20+
}
21+
let mut counter = csr.start.clone();
22+
for e in edges.iter() {
23+
csr.elist[counter[e.0]] = e.1;
24+
counter[e.0] += 1;
25+
}
26+
csr
27+
}
28+
}
29+
30+
#[derive(Copy, Clone)]
31+
struct _Edge {
32+
to: usize,
33+
}
34+
35+
/// Reference:
36+
/// R. Tarjan,
37+
/// Depth-First Search and Linear Graph Algorithms
38+
pub struct SccGraph {
39+
n: usize,
40+
edges: Vec<(usize, _Edge)>,
41+
}
42+
43+
impl SccGraph {
44+
pub fn new(n: usize) -> Self {
45+
SccGraph { n, edges: vec![] }
46+
}
47+
48+
pub fn num_vertices(&self) -> usize {
49+
self.n
50+
}
51+
52+
pub fn add_edge(&mut self, from: usize, to: usize) {
53+
self.edges.push((from, _Edge { to }));
54+
}
55+
56+
/// return pair of (# of scc, scc id)
57+
pub fn scc_ids(&self) -> (usize, Vec<usize>) {
58+
// In C++ ac-library, this function is implemented by using recursive lambda functions.
59+
// Instead, we use fn and struct for capturing environments.
60+
struct _Env {
61+
g: Csr<_Edge>,
62+
now_ord: usize,
63+
group_num: usize,
64+
visited: Vec<usize>,
65+
low: Vec<usize>,
66+
ord: Vec<Option<usize>>,
67+
ids: Vec<usize>,
68+
}
69+
let mut env = _Env {
70+
g: Csr::new(self.n, &self.edges, _Edge { to: 0 }),
71+
now_ord: 0,
72+
group_num: 0,
73+
visited: Vec::with_capacity(self.n),
74+
low: vec![0; self.n],
75+
ord: vec![None; self.n],
76+
ids: vec![0; self.n],
77+
};
78+
79+
fn dfs(v: usize, n: usize, env: &mut _Env) {
80+
env.low[v] = env.now_ord;
81+
env.ord[v] = Some(env.now_ord);
82+
env.now_ord += 1;
83+
env.visited.push(v);
84+
85+
for i in env.g.start[v]..env.g.start[v + 1] {
86+
let to = env.g.elist[i].to;
87+
if let Some(x) = env.ord[to] {
88+
env.low[v] = std::cmp::min(env.low[v], x);
89+
} else {
90+
dfs(to, n, env);
91+
env.low[v] = std::cmp::min(env.low[v], env.low[to]);
92+
}
93+
}
94+
if env.low[v] == env.ord[v].unwrap() {
95+
loop {
96+
let u = *env.visited.last().unwrap();
97+
env.visited.pop();
98+
env.ord[u] = Some(n);
99+
env.ids[u] = env.group_num;
100+
if u == v {
101+
break;
102+
}
103+
}
104+
env.group_num += 1;
105+
}
106+
}
107+
for i in 0..self.n {
108+
if env.ord[i].is_none() {
109+
dfs(i, self.n, &mut env);
110+
}
111+
}
112+
for x in env.ids.iter_mut() {
113+
*x = env.group_num - 1 - *x;
114+
}
115+
(env.group_num, env.ids)
116+
}
117+
118+
pub fn scc(&self) -> Vec<Vec<usize>> {
119+
let ids = self.scc_ids();
120+
let group_num = ids.0;
121+
let mut counts = vec![0usize; group_num];
122+
for &x in ids.1.iter() {
123+
counts[x] += 1;
124+
}
125+
let mut groups: Vec<Vec<usize>> = (0..ids.0).map(|_| vec![]).collect();
126+
for i in 0..group_num {
127+
groups[i].reserve(counts[i]);
128+
}
129+
for i in 0..self.n {
130+
groups[ids.1[i]].push(i);
131+
}
132+
groups
133+
}
134+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub use modint::{
2626
Barrett, DefaultId, DynamicModInt, Id, Mod1000000007, Mod998244353, ModInt, ModInt1000000007,
2727
ModInt998244353, Modulus, RemEuclidU32, StaticModInt,
2828
};
29+
pub use scc::SccGraph;
2930
pub use segtree::{Monoid, Segtree};
3031
pub use string::{
3132
lcp_array, lcp_array_arbitrary, suffix_array, suffix_array_arbitrary, suffix_array_manual,

src/scc.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,63 @@
1+
use crate::internal_scc;
12

3+
pub struct SccGraph {
4+
internal: internal_scc::SccGraph,
5+
}
6+
7+
impl SccGraph {
8+
pub fn new(n: usize) -> Self {
9+
SccGraph {
10+
internal: internal_scc::SccGraph::new(n),
11+
}
12+
}
13+
14+
pub fn add_edge(&mut self, from: usize, to: usize) {
15+
let n = self.internal.num_vertices();
16+
assert!(from < n);
17+
assert!(to < n);
18+
self.internal.add_edge(from, to);
19+
}
20+
21+
pub fn scc(&self) -> Vec<Vec<usize>> {
22+
self.internal.scc()
23+
}
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use super::*;
29+
30+
#[test]
31+
fn test_scc_simple() {
32+
let mut graph = SccGraph::new(2);
33+
graph.add_edge(0, 1);
34+
graph.add_edge(1, 0);
35+
let scc = graph.scc();
36+
assert_eq!(scc.len(), 1);
37+
}
38+
39+
#[test]
40+
fn test_scc_self_loop() {
41+
let mut graph = SccGraph::new(2);
42+
graph.add_edge(0, 0);
43+
graph.add_edge(0, 0);
44+
graph.add_edge(1, 1);
45+
let scc = graph.scc();
46+
assert_eq!(scc.len(), 2);
47+
}
48+
49+
#[test]
50+
fn solve_alpc_g_sample1() {
51+
// https://atcoder.jp/contests/practice2/tasks/practice2_g
52+
let n: usize = 6;
53+
let edges = vec![(1, 4), (5, 2), (3, 0), (5, 5), (4, 1), (0, 3), (4, 2)];
54+
55+
let mut graph = SccGraph::new(n);
56+
for (u, v) in edges.into_iter() {
57+
graph.add_edge(u, v);
58+
}
59+
60+
let scc = graph.scc();
61+
assert_eq!(scc, vec![vec![5], vec![1, 4], vec![2], vec![0, 3]]);
62+
}
63+
}

0 commit comments

Comments
 (0)