| 
 | 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