123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- "use strict";
- 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;
- }
|