Spaces:
Sleeping
Sleeping
; | |
module.exports = tarjan; | |
// Adapted from https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm#The_algorithm_in_pseudocode | |
function tarjan(graph) { | |
const indices = new Map(); | |
const lowlinks = new Map(); | |
const onStack = new Set(); | |
const stack = []; | |
const scc = []; | |
let idx = 0; | |
function strongConnect(v) { | |
indices.set(v, idx); | |
lowlinks.set(v, idx); | |
idx++; | |
stack.push(v); | |
onStack.add(v); | |
const deps = graph.get(v); | |
for (const dep of deps) { | |
if (!indices.has(dep)) { | |
strongConnect(dep); | |
lowlinks.set(v, Math.min(lowlinks.get(v), lowlinks.get(dep))); | |
} else if (onStack.has(dep)) { | |
lowlinks.set(v, Math.min(lowlinks.get(v), indices.get(dep))); | |
} | |
} | |
if (lowlinks.get(v) === indices.get(v)) { | |
const vertices = new Set(); | |
let w = null; | |
while (v !== w) { | |
w = stack.pop(); | |
onStack.delete(w); | |
vertices.add(w); | |
} | |
scc.push(vertices); | |
} | |
} | |
for (const v of graph.keys()) { | |
if (!indices.has(v)) { | |
strongConnect(v); | |
} | |
} | |
return scc; | |
} | |