|
| 1 | +//! A `SccGraph` is a directed graph that calculates strongly connected components (SCC) in $O(|V| + |E|)$. |
| 2 | +
|
1 | 3 | use crate::internal_scc;
|
2 | 4 |
|
| 5 | +/// An `SccGraph` is a directed graph that calculates strongly connected components (SCC) in $O(|V| + |E|)$. |
| 6 | +/// |
| 7 | +/// # Example |
| 8 | +/// |
| 9 | +/// ``` |
| 10 | +/// use ac_library_rs::SccGraph; |
| 11 | +/// use proconio::{input, source::once::OnceSource}; |
| 12 | +/// |
| 13 | +/// input! { |
| 14 | +/// from OnceSource::from( |
| 15 | +/// "5\n\ |
| 16 | +/// 5\n\ |
| 17 | +/// 0 1\n\ |
| 18 | +/// 1 2\n\ |
| 19 | +/// 2 0\n\ |
| 20 | +/// 0 3\n\ |
| 21 | +/// 3 4\n", |
| 22 | +/// ), |
| 23 | +/// n: usize, |
| 24 | +/// abs: [(usize, usize)], |
| 25 | +/// } |
| 26 | +/// |
| 27 | +/// let mut graph = SccGraph::new(n); |
| 28 | +/// for (a, b) in abs { |
| 29 | +/// graph.add_edge(a, b); |
| 30 | +/// } |
| 31 | +/// |
| 32 | +/// assert_eq!(graph.scc(), [&[0, 1, 2][..], &[3], &[4]]); |
| 33 | +/// ``` |
3 | 34 | pub struct SccGraph {
|
4 | 35 | internal: internal_scc::SccGraph,
|
5 | 36 | }
|
6 | 37 |
|
7 | 38 | impl SccGraph {
|
| 39 | + /// Creates a new `SccGraph` with `n` edges. |
| 40 | + /// |
| 41 | + /// # Constraints |
| 42 | + /// |
| 43 | + /// - $0 \leq n \leq 10^8$ |
| 44 | + /// |
| 45 | + /// # Complexity |
| 46 | + /// |
| 47 | + /// - $O(n)$ |
8 | 48 | pub fn new(n: usize) -> Self {
|
9 | 49 | SccGraph {
|
10 | 50 | internal: internal_scc::SccGraph::new(n),
|
11 | 51 | }
|
12 | 52 | }
|
13 | 53 |
|
| 54 | + /// Adds a directed edge from the vertex `from` to the vertex `to`. |
| 55 | + /// |
| 56 | + /// # Constraints |
| 57 | + /// |
| 58 | + /// - $0 \leq$ `from` $< n$ |
| 59 | + /// - $0 \leq$ `to` $< n$ |
| 60 | + /// |
| 61 | + /// # Panics |
| 62 | + /// |
| 63 | + /// Panics if the above constraints are not satisfied. |
| 64 | + /// |
| 65 | + /// # Complexity |
| 66 | + /// |
| 67 | + /// - $O(1)$ amortized |
14 | 68 | pub fn add_edge(&mut self, from: usize, to: usize) {
|
15 | 69 | let n = self.internal.num_vertices();
|
16 | 70 | assert!(from < n);
|
17 | 71 | assert!(to < n);
|
18 | 72 | self.internal.add_edge(from, to);
|
19 | 73 | }
|
20 | 74 |
|
| 75 | + /// Calculates the strongly connected components (SCC) of directed graphs in $O(|V| + |E|)$. |
| 76 | + /// |
| 77 | + /// Returns the list of the "list of the vertices" that satisfies the following. |
| 78 | + /// |
| 79 | + /// - Each vertex is in exactly one "list of the vertices". |
| 80 | + /// - Each "list of the vertices" corresponds to the vertex set of a strongly connected component. The order of the vertices in the list is undefined. |
| 81 | + /// - The list of "list of the vertices" are sorted in topological order, i.e., for two vertices $u$, $v$ in different strongly connected components, if there is a directed path from $u$ to $v$, the list containing $u$ appears earlier than the list containing $v$. |
| 82 | + /// |
| 83 | + /// # Complexity |
| 84 | + /// |
| 85 | + /// - $O(n + m)$ where $m$ is the number of added edges |
21 | 86 | pub fn scc(&self) -> Vec<Vec<usize>> {
|
22 | 87 | self.internal.scc()
|
23 | 88 | }
|
|
0 commit comments