"""Iterative Tarjan strongly connected components (no recursion limit).""" from __future__ import annotations from typing import Dict, Iterable, List, Tuple def scc(adj: Dict[int, Iterable[int]]) -> List[List[int]]: index_counter = [0] stack: List[int] = [] on_stack: set = set() indices: Dict[int, int] = {} lowlink: Dict[int, int] = {} result: List[List[int]] = [] for u in list(adj.keys()): if u in indices: continue call_stack: List[Tuple[int, iter]] = [(u, iter(adj.get(u, ())))] indices[u] = lowlink[u] = index_counter[0] index_counter[0] += 1 stack.append(u) on_stack.add(u) while call_stack: v, it = call_stack[-1] advanced = False for w in it: if w not in indices: indices[w] = lowlink[w] = index_counter[0] index_counter[0] += 1 stack.append(w) on_stack.add(w) call_stack.append((w, iter(adj.get(w, ())))) advanced = True break elif w in on_stack: if indices[w] < lowlink[v]: lowlink[v] = indices[w] call_stack[-1] = (v, it) if advanced: continue call_stack.pop() if call_stack: parent = call_stack[-1][0] if lowlink[v] < lowlink[parent]: lowlink[parent] = lowlink[v] if lowlink[v] == indices[v]: comp = [] while True: w = stack.pop() on_stack.discard(w) comp.append(w) if w == v: break result.append(comp) return result