dsalgo 0.2.6

A package for Datastructures and Algorithms.
Documentation
pub fn lowlink(g: &Vec<Vec<usize>>) -> (Vec<usize>, Vec<usize>) {
    let n = g.len();
    let mut order = vec![n; n];
    let mut low = vec![n; n];
    fn dfs(
        g: &Vec<Vec<usize>>,
        u: usize,
        parent: usize,
        ord: &mut usize,
        order: &mut Vec<usize>,
        low: &mut Vec<usize>,
    ) {
        let n = g.len();
        order[u] = *ord;
        *ord += 1;
        low[u] = order[u];
        for v in g[u].iter().map(|x| *x) {
            if v == parent {
                continue;
            }
            if order[v] != n {
                if order[v] < low[u] {
                    low[u] = order[v];
                }
                continue;
            }
            dfs(g, v, u, ord, order, low);
            if low[v] < low[u] {
                low[u] = low[v];
            }
        }
    }
    let mut ord = 0;
    for i in 0..n {
        if order[i] != n {
            continue;
        }
        dfs(g, i, n, &mut ord, &mut order, &mut low);
    }
    (order, low)
}

pub fn bridges(n: usize, g: &Vec<(usize, usize)>) -> Vec<(usize, usize)> {
    let mut t = vec![vec![]; n];
    for (u, v) in g {
        t[*u].push(*v);
        t[*v].push(*u);
    }
    let (order, low) = lowlink(&t);
    let mut bridges = Vec::new();
    for (u, v) in g {
        let mut u = *u;
        let mut v = *v;
        if order[u] > order[v] {
            std::mem::swap(&mut u, &mut v);
        }
        if low[v] <= order[u] {
            continue;
        }
        if u > v {
            std::mem::swap(&mut u, &mut v);
        }
        bridges.push((u, v));
    }
    bridges.sort();
    bridges
}

pub fn articulation_points(g: &Vec<Vec<usize>>) -> Vec<usize> {
    let n = g.len();
    let mut articulation_points = Vec::new();
    let (order, low) = lowlink(g);
    let mut visited = vec![false; n];
    fn dfs(
        g: &Vec<Vec<usize>>,
        u: usize,
        parent: usize,
        visited: &mut Vec<bool>,
        order: &Vec<usize>,
        low: &Vec<usize>,
        points: &mut Vec<usize>,
    ) {
        let n = g.len();
        visited[u] = true;
        let mut cnt = 0u32;
        let mut is_articulation = false;
        for v in g[u].iter().map(|x| *x) {
            if visited[v] {
                continue;
            }
            cnt += 1;
            dfs(g, v, u, visited, order, low, points);
            if parent == n || low[v] < order[u] {
                continue;
            }
            is_articulation = true;
        }
        if parent == n && cnt >= 2 {
            is_articulation = true;
        }
        if is_articulation {
            points.push(u);
        }
    }
    for i in 0..n {
        if visited[i] {
            continue;
        }
        dfs(g, i, n, &mut visited, &order, &low, &mut articulation_points);
    }
    articulation_points.sort();
    articulation_points
}