1
1
2
2
3
+ // Represents a union of disjoint sets. Each set's elements are arranged in a
4
+ // tree, whose root is the set's representative.
3
5
pub struct DisjointSets {
4
6
parent : Vec < usize >
5
7
}
6
8
7
9
impl DisjointSets {
10
+ // Initialize disjoint sets containing one element each.
8
11
pub fn new ( size : usize ) -> DisjointSets {
9
12
DisjointSets { parent : ( 0 ..size) . collect ( ) }
10
13
}
11
14
15
+ // Find the set's representative. Do path compression along the way to make
16
+ // future queries faster.
12
17
pub fn find ( & mut self , u : usize ) -> usize {
13
18
let pu = self . parent [ u] ;
14
19
if pu != u { self . parent [ u] = self . find ( pu) ; }
15
20
self . parent [ u]
16
21
}
17
22
18
- // Returns true if u and v were previously in different sets.
23
+ // Merge the sets containing u and v into a single set containing their
24
+ // union. Returns true if u and v were previously in different sets.
19
25
pub fn merge ( & mut self , u : usize , v : usize ) -> bool {
20
26
let ( pu, pv) = ( self . find ( u) , self . find ( v) ) ;
21
27
self . parent [ pu] = pv;
22
28
pu != pv
23
29
}
24
30
}
25
31
32
+ // A compact graph representation.
26
33
pub struct Graph {
27
34
pub first : Vec < Option < usize > > ,
28
35
pub next : Vec < Option < usize > > ,
29
36
pub endp : Vec < usize > ,
30
37
}
31
38
32
39
impl Graph {
40
+ // Initialize a graph with vmax vertices and no edges. For best efficiency,
41
+ // emax should be a tight upper bound on the number of edges to insert.
33
42
pub fn new ( vmax : usize , emax : usize ) -> Graph {
34
43
Graph {
35
44
first : vec ! [ None ; vmax] ,
@@ -38,44 +47,52 @@ impl Graph {
38
47
}
39
48
}
40
49
50
+ // Utilities to compute the number of vertices and edges.
41
51
pub fn num_v ( & self ) -> usize { self . first . len ( ) }
42
52
pub fn num_e ( & self ) -> usize { self . next . len ( ) }
43
53
54
+ // Add a directed edge from u to v.
44
55
pub fn add_edge ( & mut self , u : usize , v : usize ) {
45
56
self . next . push ( self . first [ u] ) ;
46
57
self . first [ u] = Some ( self . endp . len ( ) ) ;
47
58
self . endp . push ( v) ;
48
59
}
49
60
61
+ // An undirected edge is two directed edges. If edges are added only via
62
+ // this funcion, the reverse of any edge e can be found at e^1.
50
63
pub fn add_undirected_edge ( & mut self , u : usize , v : usize ) {
51
64
self . add_edge ( u, v) ;
52
65
self . add_edge ( v, u) ;
53
66
}
54
67
55
- // Assumes odd-numbered vertices correspond to predecessors' negations.
56
- // Logically equivalent forms: u || v, !u -> v, !v -> u
68
+ // If we think of each even-numbered vertex as a variable, and its successor
69
+ // as its negation, then we can build the implication graph corresponding
70
+ // to any 2-CNF formula. Note that u||v == !u -> v == !v -> u.
57
71
pub fn add_two_sat_clause ( & mut self , u : usize , v : usize ) {
58
72
self . add_edge ( u^1 , v) ;
59
73
self . add_edge ( v^1 , u) ;
60
74
}
61
75
76
+ // Gets vertex u's adjacency list.
62
77
pub fn adj_list < ' a > ( & ' a self , u : usize ) -> AdjListIterator < ' a > {
63
78
AdjListIterator {
64
79
graph : self ,
65
80
next_e : self . first [ u]
66
81
}
67
82
}
68
83
84
+ // Helper function used by euler_path. Note that we can't consume the
85
+ // adjacency list in a for loop because recursive calls may need it.
69
86
fn euler_recurse ( & self , u : usize , adj : & mut [ AdjListIterator ] , edges : & mut Vec < usize > ) {
70
87
while let Some ( ( e, v) ) = adj[ u] . next ( ) {
71
88
self . euler_recurse ( v, adj, edges) ;
72
89
edges. push ( e) ;
73
90
}
74
91
}
75
92
76
- // Finds an Euler path starting from u, assuming it exists, and that the
77
- // graph is directed. To deal with undirected graphs, one simply needs to
78
- // keep track of visited edges to avoid repeating them .
93
+ // Finds the sequence of edges in an Euler path starting from u, assuming it
94
+ // exists and that the graph is directed. To extend this to undirected
95
+ // graphs, keep track of a visited array to skip the reverse edge .
79
96
pub fn euler_path ( & self , u : usize ) -> Vec < usize > {
80
97
let mut adj_iters = ( 0 ..self . num_v ( ) ) . map ( |u| self . adj_list ( u) )
81
98
. collect :: < Vec < _ > > ( ) ;
@@ -86,15 +103,16 @@ impl Graph {
86
103
}
87
104
}
88
105
106
+ // An iterator for convenient adjacency list traversal.
89
107
pub struct AdjListIterator < ' a > {
90
108
graph : & ' a Graph ,
91
109
next_e : Option < usize >
92
110
}
93
111
94
112
impl < ' a > Iterator for AdjListIterator < ' a > {
95
- // Produces an outgoing edge and vertex.
96
113
type Item = ( usize , usize ) ;
97
-
114
+
115
+ // Produces an outgoing edge and vertex.
98
116
fn next ( & mut self ) -> Option < Self :: Item > {
99
117
self . next_e . map ( |e| {
100
118
let v = self . graph . endp [ e] ;
@@ -104,7 +122,7 @@ impl<'a> Iterator for AdjListIterator<'a> {
104
122
}
105
123
}
106
124
107
- // Assumes graph is undirected.
125
+ // Kruskal's minimum spanning tree algorithm on an undirected graph .
108
126
pub fn min_spanning_tree ( graph : & Graph , weights : & [ i64 ] ) -> Vec < usize > {
109
127
assert_eq ! ( graph. num_e( ) , 2 * weights. len( ) ) ;
110
128
let mut edges = ( 0 ..weights. len ( ) ) . collect :: < Vec < _ > > ( ) ;
@@ -190,8 +208,8 @@ impl FlowGraph {
190
208
self . vdata [ t] . lev != None
191
209
}
192
210
193
- // Dinic's fast maximum flow: V^2E in general,
194
- // min(V^(2/3),sqrt(E))E on unit caps , sqrt(V)E on bipartite
211
+ // Dinic's maximum flow / Hopcroft-Karp maximum bipartite matching : V^2E in
212
+ // general, min(V^(2/3),sqrt(E))E on unit capacity , sqrt(V)E on bipartite.
195
213
pub fn dinic ( & mut self , s : usize , t : usize ) -> i64 {
196
214
let mut flow = 0 ;
197
215
while self . bfs ( s, t) {
@@ -209,7 +227,7 @@ impl FlowGraph {
209
227
}
210
228
}
211
229
212
- // 2-vertex and 2-edge connected components
230
+ // Strongly connected, 2-vertex-connected, and 2-edge- connected components
213
231
// should handle multiple-edges and self-loops
214
232
// USAGE: 1) new(); 2) add_edge(...); 3) compute_bcc();
215
233
// 4) use is_cut_vertex(vertex_index) or is_cut_edge(2 * edge_index)
0 commit comments