dsalgo 0.2.6

A package for Datastructures and Algorithms.
Documentation
pub fn path_based(g: &Vec<Vec<usize>>) -> Vec<usize> {
    fn dfs(
        g: &Vec<Vec<usize>>,
        order: &mut Vec<usize>,
        label: &mut Vec<usize>,
        st_0: &mut Vec<usize>,
        st_1: &mut Vec<usize>,
        u: usize,
        ord: &mut usize,
        l: &mut usize,
    ) {
        order[u] = *ord;
        *ord += 1;
        st_0.push(u);
        st_1.push(u);
        for v in g[u].iter().map(|x| *x) {
            if order[v] == g.len() {
                dfs(g, order, label, st_0, st_1, v, ord, l);
            } else if label[v] == g.len() {
                while order[*st_0.last().unwrap()] > order[v] {
                    st_0.pop();
                }
            }
        }
        if *st_0.last().unwrap() == u {
            loop {
                let v = st_1.pop().unwrap();
                label[v] = *l;
                if v == u {
                    break;
                }
            }
            *l += 1;
            st_0.pop();
        }
    }
    let n = g.len();
    let mut order = vec![n; n];
    let mut label = vec![n; n];
    let mut st_0 = Vec::with_capacity(n);
    let mut st_1 = Vec::with_capacity(n);
    let mut ord = 0;
    let mut l = 0;
    for i in 0..n {
        if order[i] == n {
            dfs(
                g, &mut order, &mut label, &mut st_0, &mut st_1, i, &mut ord,
                &mut l,
            );
        }
    }
    label
}

pub fn tarjan_offline(g: &Vec<Vec<usize>>) -> Vec<usize> {
    fn dfs(
        g: &Vec<Vec<usize>>,
        order: &mut Vec<usize>,
        low: &mut Vec<usize>,
        label: &mut Vec<usize>,
        on_stack: &mut Vec<bool>,
        st: &mut Vec<usize>,
        u: usize,
        ord: &mut usize,
        l: &mut usize,
    ) {
        order[u] = *ord;
        low[u] = *ord;
        *ord += 1;
        st.push(u);
        on_stack[u] = true;
        for v in g[u].iter().map(|x| *x) {
            if order[v] == g.len() {
                dfs(g, order, low, label, on_stack, st, v, ord, l);
                if low[v] < low[u] {
                    low[u] = low[v];
                }
            } else if on_stack[v] && order[v] < low[u] {
                low[u] = order[v];
            }
        }
        if low[u] == order[u] {
            loop {
                let v = st.pop().unwrap();
                on_stack[v] = false;
                label[v] = *l;
                if v == u {
                    break;
                }
            }
            *l += 1;
        }
    }
    let n = g.len();
    let mut order = vec![n; n];
    let mut low = vec![n; n];
    let mut label = vec![n; n];
    let mut on_stack = vec![false; n];
    let mut st = Vec::with_capacity(n);
    let mut ord = 0;
    let mut l = 0;
    for i in 0..n {
        if order[i] == n {
            dfs(
                g,
                &mut order,
                &mut low,
                &mut label,
                &mut on_stack,
                &mut st,
                i,
                &mut ord,
                &mut l,
            );
        }
    }
    label
}

pub fn kosaraju(g: &Vec<Vec<usize>>) -> Vec<usize> {
    fn dfs(
        g: &Vec<Vec<usize>>,
        visited: &mut Vec<bool>,
        que: &mut Vec<usize>,
        u: usize,
    ) {
        visited[u] = true;
        for v in g[u].iter() {
            if !visited[*v] {
                dfs(g, visited, que, *v);
            }
        }
        que.push(u);
    }
    fn rev_dfs(
        g: &Vec<Vec<usize>>,
        label: &mut Vec<usize>,
        l: usize,
        u: usize,
    ) {
        label[u] = l;
        for v in g[u].iter() {
            if label[*v] == g.len() {
                rev_dfs(g, label, l, *v);
            }
        }
    }
    let n = g.len();
    let mut visited = vec![false; n];
    let mut que = Vec::with_capacity(n);
    let mut label = vec![n; n];
    let mut l = 0usize;
    for i in 0..n {
        if !visited[i] {
            dfs(g, &mut visited, &mut que, i);
        }
    }
    let mut t = vec![vec![]; n];
    for u in 0..n {
        for v in g[u].iter() {
            t[*v].push(u);
        }
    }
    for i in que.iter().rev() {
        if label[*i] != n {
            continue;
        }
        rev_dfs(&t, &mut label, l, *i);
        l += 1;
    }
    label
}