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; | |
| } | |