tarjan
Tarjan's SCC. Components come out dependencies-first.
export function tarjan(n: number, succ: (v: number) => Iterable<number>): number[][] { let counter = 0; const index = Array.from({ length: n }, () => -1); const low = Array.from({ length: n }, () => 0); const onStack = Array.from({ length: n }, () => false); const stack: number[] = []; const out: number[][] = []; const strong = (v: number) => { index[v] = low[v] = counter++; stack.push(v); onStack[v] = true; for (const w of succ(v)) { if (index[w] === -1) { strong(w); low[v] = Math.min(low[v]!, low[w]!); } else if (onStack[w]) low[v] = Math.min(low[v]!, index[w]!); } if (low[v] === index[v]) { const comp: number[] = []; let w: number; do { w = stack.pop()!; onStack[w] = false; comp.push(w); } while (w !== v); out.push(comp.sort((a, b) => a - b)); } }; for (let v = 0; v < n; v++) if (index[v] === -1) strong(v); return out; }