Set CUT_VERTICES = {}
int dfsnum = 0
// define v.low to be the lowest dfs number
// of a non-outputted vertex reachable
// by using at most one-non tree edge.
foreach v in V
if (v.dfsnum is not defined)
findcut(v,null)
// parent is the vertex that called findcut
// if u is root, parent = null
void findcut(vertex v, vertex parent)
{
// children here refer to children of v in the dfs tree
// hence, children cannot be connected except thru v (in the tree)
int children = 0
v.dfsnum = dfsnum++
v.low = v.dfsnum
foreach (v,u) in E
{
if (u.dfsnum is not defined) {
// u is a child of v
// i.e. v is a parent of u
children++
findcut(u,v)
v.low = min(v.low, u.low)
}else if (u.dfsnum is defined && u != parent) {
// i.e. u is not parent of v
// u must be an ancestor
v.low = min(v.low, u.dfsnum)
}
// v is not a root...
if (parent != null && v.low >= parent.dfsnum) {
// Since the low of parent's childrens are higher than
// parent's low, there is no back edge to parent's ancestors
// i.e. if parent is removed, there is no way children can be
// connected to ancestors
// so parent has to be a cut vertex
CUT_VERTICES.add(parent)
}
}
// v is a root (special case)
if (parent == null && children >= 2) {
CUT_VERTICES.add(v)
}
}