use crate::graph::graph::Graph;
pub struct EulerTour {
graph: Graph,
l: Vec<usize>,
r: Vec<usize>,
t: usize,
}
impl EulerTour {
const INF: usize = 100_000_000_000_000_000;
pub fn new(n: usize, graph: Graph) -> Self {
let l = vec![Self::INF; n];
let r = vec![Self::INF; n];
Self { graph, l, r, t: 1 }
}
pub fn traverse(&mut self, root: usize) -> (&[usize], &[usize]) {
self._dfs(root, None);
for i in 0..self.l.len() {
if self.r[i] == Self::INF {
self.r[i] = self.l[i];
}
}
(&self.l, &self.r)
}
fn _dfs(&mut self, u: usize, p: Option<usize>) {
self.l[u] = self.t;
self.t += 1;
for i in 0..self.graph.graph[u].len() {
let (v, _) = self.graph.graph[u][i];
if p != Some(v) {
self._dfs(v, Some(u));
self.r[u] = self.t;
self.t += 1;
}
}
}
}
#[cfg(test)]
mod test_euler_tour {
use crate::graph::euler_tour::EulerTour;
use crate::graph::graph::Graph;
#[test]
fn it_works() {
let mut graph = Graph::new(7, false);
graph.connect_unweighted(0, 1);
graph.connect_unweighted(1, 2);
graph.connect_unweighted(1, 3);
graph.connect_unweighted(3, 4);
graph.connect_unweighted(0, 5);
graph.connect_unweighted(5, 6);
let mut euler_tour = EulerTour::new(7, graph);
let (l, r) = euler_tour.traverse(0);
assert_eq!(l, &vec![1, 2, 3, 5, 6, 10, 11]);
assert_eq!(r, &vec![13, 8, 3, 7, 6, 12, 11]);
}
}