haar_lib/graph/
detect_cycle.rs1use crate::graph::*;
4
5#[derive(Clone, Copy, PartialEq, Eq)]
6enum Status {
7 Unchecked,
8 Searched,
9 Searching,
10}
11
12pub fn detect_cycle<D: Direction, E: EdgeTrait>(g: &Graph<D, E>) -> Option<Vec<&E>> {
14 let size = g.len();
15 let mut check = vec![Status::Unchecked; size];
16
17 for i in 0..size {
18 if check[i] == Status::Unchecked {
19 let mut ret = vec![];
20 rec(g, i, &mut ret, &mut check);
21
22 if !ret.is_empty() {
23 ret.reverse();
24 return Some(ret);
25 }
26 }
27 }
28
29 None
30}
31
32fn rec<'a, D: Direction, E: EdgeTrait>(
33 g: &'a Graph<D, E>,
34 cur: usize,
35 ret: &mut Vec<&'a E>,
36 check: &mut [Status],
37) -> Option<isize> {
38 match check[cur] {
39 Status::Searched => None,
40 Status::Searching => Some(cur as isize),
41 Status::Unchecked => {
42 check[cur] = Status::Searching;
43
44 for e in g.nodes[cur].edges.iter() {
45 if let Some(res) = rec(g, e.to(), ret, check) {
46 if res != -1 {
47 ret.push(e);
48 if res == cur as isize {
49 return Some(-1);
50 }
51 }
52
53 return Some(res);
54 }
55 }
56
57 check[cur] = Status::Searched;
58
59 None
60 }
61 }
62}