1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#[derive(Debug)] pub enum Vertex { In(usize), Out(usize), } impl Vertex { pub fn get_value(&self) -> usize { match self { Vertex::In(value) => *value, Vertex::Out(value) => *value, } } } use std::collections::VecDeque; pub fn euler_tour(e: &[Vec<usize>], root: usize) -> (Vec<usize>, Vec<usize>, Vec<usize>) { let mut stack = VecDeque::new(); stack.push_back(Vertex::In(root)); let mut tour = vec![]; let mut first_look = vec![None; e.len()]; let mut depth = 0; let mut depths = vec![0; e.len()]; while let Some(vertex) = stack.pop_back() { if let Vertex::In(v) = vertex { for &to in e[v].iter() { if first_look[to].is_some() { continue; } stack.push_back(Vertex::Out(v)); stack.push_back(Vertex::In(to)); } first_look[v] = Some(tour.len()); depths[v] = depth; depth += 1; } else { depth -= 1; } tour.push(vertex.get_value()); } ( tour, first_look.iter().map(|x| x.unwrap()).collect(), depths, ) } #[cfg(test)] mod tests { use super::*; #[test] fn test_eiler_tour() { let e = vec![vec![5, 1], vec![4, 2], vec![3], vec![], vec![], vec![]]; let (ans, _, _) = euler_tour(&e, 0); assert_eq!(&ans, &[0, 1, 2, 3, 2, 1, 4, 1, 0, 5, 0]); } }