contest_algorithms/graph/
util.rs1use super::{DisjointSets, Graph};
2use crate::graph::AdjListIterator;
3use std::cmp::Reverse;
4
5impl Graph {
6 pub fn euler_path(&self, u: usize) -> Vec<usize> {
11 let mut adj_iters = (0..self.num_v())
12 .map(|u| self.adj_list(u))
13 .collect::<Vec<_>>();
14 let mut edges = Vec::with_capacity(self.num_e());
15 self.euler_recurse(u, &mut adj_iters, &mut edges);
16 edges.reverse();
17 edges
18 }
19
20 fn euler_recurse(&self, u: usize, adj: &mut [AdjListIterator], edges: &mut Vec<usize>) {
23 while let Some((e, v)) = adj[u].next() {
24 self.euler_recurse(v, adj, edges);
25 edges.push(e);
26 }
27 }
28
29 pub fn min_spanning_tree(&self, weights: &[i64]) -> Vec<usize> {
31 assert_eq!(self.num_e(), 2 * weights.len());
32 let mut edges = (0..weights.len()).collect::<Vec<_>>();
33 edges.sort_unstable_by_key(|&e| weights[e]);
34
35 let mut components = DisjointSets::new(self.num_v());
36 edges
37 .into_iter()
38 .filter(|&e| components.merge(self.endp[2 * e], self.endp[2 * e + 1]))
39 .collect()
40 }
41
42 pub fn dijkstra(&self, weights: &[u64], u: usize) -> Vec<u64> {
44 assert_eq!(self.num_e(), weights.len());
45 let mut dist = vec![u64::max_value(); weights.len()];
46 let mut heap = std::collections::BinaryHeap::new();
47
48 dist[u] = 0;
49 heap.push((Reverse(0), 0));
50 while let Some((Reverse(dist_u), u)) = heap.pop() {
51 if dist[u] == dist_u {
52 for (e, v) in self.adj_list(u) {
53 let dist_v = dist_u + weights[e];
54 if dist[v] > dist_v {
55 dist[v] = dist_v;
56 heap.push((Reverse(dist_v), v));
57 }
58 }
59 }
60 }
61 dist
62 }
63
64 pub fn dfs(&self, root: usize) -> DfsIterator {
65 let mut visited = vec![false; self.num_v()];
66 visited[root] = true;
67 let adj_iters = (0..self.num_v())
68 .map(|u| self.adj_list(u))
69 .collect::<Vec<_>>();
70
71 DfsIterator {
72 visited,
73 stack: vec![root],
74 adj_iters,
75 }
76 }
77}
78
79pub struct DfsIterator<'a> {
80 visited: Vec<bool>,
81 stack: Vec<usize>,
82 adj_iters: Vec<AdjListIterator<'a>>,
83}
84
85impl<'a> Iterator for DfsIterator<'a> {
86 type Item = (usize, usize);
87
88 fn next(&mut self) -> Option<Self::Item> {
92 loop {
93 let &u = self.stack.last()?;
94 while let Some((e, v)) = self.adj_iters[u].next() {
95 if !self.visited[v] {
96 self.visited[v] = true;
97 self.stack.push(v);
98 return Some((e, v));
99 }
100 }
101 self.stack.pop();
102 }
103 }
104}
105
106#[cfg(test)]
107mod test {
108 use super::*;
109
110 #[test]
111 fn test_euler() {
112 let mut graph = Graph::new(3, 4);
113 graph.add_edge(0, 1);
114 graph.add_edge(1, 0);
115 graph.add_edge(1, 2);
116 graph.add_edge(2, 1);
117
118 assert_eq!(graph.euler_path(0), vec![0, 2, 3, 1]);
119 }
120
121 #[test]
122 fn test_min_spanning_tree() {
123 let mut graph = Graph::new(3, 6);
124 graph.add_undirected_edge(0, 1);
125 graph.add_undirected_edge(1, 2);
126 graph.add_undirected_edge(2, 0);
127 let weights = [7, 3, 5];
128
129 let mst = graph.min_spanning_tree(&weights);
130 let mst_cost = mst.iter().map(|&e| weights[e]).sum::<i64>();
131 assert_eq!(mst, vec![1, 2]);
132 assert_eq!(mst_cost, 8);
133 }
134
135 #[test]
136 fn test_dijkstra() {
137 let mut graph = Graph::new(3, 3);
138 graph.add_edge(0, 1);
139 graph.add_edge(1, 2);
140 graph.add_edge(2, 0);
141 let weights = [7, 3, 5];
142
143 let dist = graph.dijkstra(&weights, 0);
144 assert_eq!(dist, vec![0, 7, 10]);
145 }
146
147 #[test]
148 fn test_dfs() {
149 let mut graph = Graph::new(4, 6);
150 graph.add_edge(0, 2);
151 graph.add_edge(2, 0);
152 graph.add_edge(1, 2);
153 graph.add_edge(0, 1);
154 graph.add_edge(3, 3);
155 graph.add_edge(2, 3);
156
157 let dfs_root = 2;
158 let dfs_traversal = std::iter::once(dfs_root)
159 .chain(graph.dfs(dfs_root).map(|(_, v)| v))
160 .collect::<Vec<_>>();
161
162 assert_eq!(dfs_traversal, vec![2, 3, 0, 1]);
163 }
164
165 #[test]
166 fn test_dfs2() {
167 let mut graph = Graph::new(5, 6);
168 graph.add_edge(0, 2);
169 graph.add_edge(2, 1);
170 graph.add_edge(1, 0);
171 graph.add_edge(0, 3);
172 graph.add_edge(3, 4);
173 graph.add_edge(4, 0);
174
175 let dfs_root = 0;
176 let dfs_traversal = std::iter::once(dfs_root)
177 .chain(graph.dfs(dfs_root).map(|(_, v)| v))
178 .collect::<Vec<_>>();
179
180 assert_eq!(dfs_traversal, vec![0, 3, 4, 2, 1]);
181 }
182
183 #[test]
184 fn test_dfs_space_complexity() {
185 let num_v = 20;
186 let mut graph = Graph::new(num_v, 0);
187 for i in 0..num_v {
188 for j in 0..num_v {
189 graph.add_undirected_edge(i, j);
190 }
191 }
192
193 let dfs_root = 7;
194 let mut dfs_search = graph.dfs(dfs_root);
195 let mut dfs_check = vec![dfs_root];
196 for _ in 1..num_v {
197 dfs_check.push(dfs_search.next().unwrap().1);
198 assert!(dfs_search.stack.len() <= num_v + 1);
199 }
200
201 dfs_check.sort();
202 dfs_check.dedup();
203 assert_eq!(0, dfs_check[0]);
204 assert_eq!(num_v, dfs_check.len());
205 assert_eq!(num_v - 1, dfs_check[num_v - 1]);
206 }
207}