contest_algorithms/graph/
mod.rs

1//! Basic graph module without explicit support for deletion.
2//!
3//! # Panics
4//!
5//! All methods will panic if given an out-of-bounds element index.
6pub mod connectivity;
7pub mod flow;
8pub mod util;
9
10/// Represents a union of disjoint sets. Each set's elements are arranged in a
11/// tree, whose root is the set's representative.
12pub struct DisjointSets {
13    parent: Vec<usize>,
14}
15
16impl DisjointSets {
17    /// Initializes disjoint sets containing one element each.
18    pub fn new(size: usize) -> Self {
19        Self {
20            parent: (0..size).collect(),
21        }
22    }
23
24    /// Finds the set's representative. Do path compression along the way to make
25    /// future queries faster.
26    pub fn find(&mut self, u: usize) -> usize {
27        let pu = self.parent[u];
28        if pu != u {
29            self.parent[u] = self.find(pu);
30        }
31        self.parent[u]
32    }
33
34    /// Merges the sets containing u and v into a single set containing their
35    /// union. Returns true if u and v were previously in different sets.
36    pub fn merge(&mut self, u: usize, v: usize) -> bool {
37        let (pu, pv) = (self.find(u), self.find(v));
38        self.parent[pu] = pv;
39        pu != pv
40    }
41}
42
43/// A compact graph representation. Edges are numbered in order of insertion.
44/// Each adjacency list consists of all edges pointing out from a given vertex.
45pub struct Graph {
46    /// Maps a vertex id to the first edge in its adjacency list.
47    first: Vec<Option<usize>>,
48    /// Maps an edge id to the next edge in the same adjacency list.
49    next: Vec<Option<usize>>,
50    /// Maps an edge id to the vertex that it points to.
51    endp: Vec<usize>,
52}
53
54impl Graph {
55    /// Initializes a graph with vmax vertices and no edges. To reduce
56    /// unnecessary allocations, emax_hint should be close to the number of
57    /// edges that will be inserted.
58    pub fn new(vmax: usize, emax_hint: usize) -> Self {
59        Self {
60            first: vec![None; vmax],
61            next: Vec::with_capacity(emax_hint),
62            endp: Vec::with_capacity(emax_hint),
63        }
64    }
65
66    /// Returns the number of vertices.
67    pub fn num_v(&self) -> usize {
68        self.first.len()
69    }
70
71    /// Returns the number of edges, double-counting undirected edges.
72    pub fn num_e(&self) -> usize {
73        self.endp.len()
74    }
75
76    /// Adds a directed edge from u to v.
77    pub fn add_edge(&mut self, u: usize, v: usize) {
78        self.next.push(self.first[u]);
79        self.first[u] = Some(self.num_e());
80        self.endp.push(v);
81    }
82
83    /// An undirected edge is two directed edges. If edges are added only via
84    /// this funcion, the reverse of any edge e can be found at e^1.
85    pub fn add_undirected_edge(&mut self, u: usize, v: usize) {
86        self.add_edge(u, v);
87        self.add_edge(v, u);
88    }
89
90    /// If we think of each even-numbered vertex as a variable, and its
91    /// odd-numbered successor as its negation, then we can build the
92    /// implication graph corresponding to any 2-CNF formula.
93    /// Note that u||v == !u -> v == !v -> u.
94    pub fn add_two_sat_clause(&mut self, u: usize, v: usize) {
95        self.add_edge(u ^ 1, v);
96        self.add_edge(v ^ 1, u);
97    }
98
99    /// Gets vertex u's adjacency list.
100    pub fn adj_list(&self, u: usize) -> AdjListIterator {
101        AdjListIterator {
102            graph: self,
103            next_e: self.first[u],
104        }
105    }
106}
107
108/// An iterator for convenient adjacency list traversal.
109pub struct AdjListIterator<'a> {
110    graph: &'a Graph,
111    next_e: Option<usize>,
112}
113
114impl<'a> Iterator for AdjListIterator<'a> {
115    type Item = (usize, usize);
116
117    /// Produces an outgoing edge and vertex.
118    fn next(&mut self) -> Option<Self::Item> {
119        self.next_e.map(|e| {
120            let v = self.graph.endp[e];
121            self.next_e = self.graph.next[e];
122            (e, v)
123        })
124    }
125}
126
127#[cfg(test)]
128mod test {
129    use super::*;
130
131    #[test]
132    fn test_adj_list() {
133        let mut graph = Graph::new(5, 6);
134        graph.add_edge(2, 3);
135        graph.add_edge(2, 4);
136        graph.add_edge(4, 1);
137        graph.add_edge(1, 2);
138        graph.add_undirected_edge(0, 2);
139
140        let adj = graph.adj_list(2).collect::<Vec<_>>();
141
142        assert_eq!(adj, vec![(5, 0), (1, 4), (0, 3)]);
143        for (e, v) in adj {
144            assert_eq!(v, graph.endp[e]);
145        }
146    }
147}