import sys, os sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from scc import scc def tarjan_recursive(adj): idx=[0]; stack=[]; on=set(); indices={}; low={}; res=[] import sys as _s _s.setrecursionlimit(100000) def strong(v): indices[v]=low[v]=idx[0]; idx[0]+=1; stack.append(v); on.add(v) for w in adj.get(v,()): if w not in indices: strong(w); low[v]=min(low[v],low[w]) elif w in on: low[v]=min(low[v],indices[w]) if low[v]==indices[v]: comp=[] while True: w=stack.pop(); on.discard(w); comp.append(w) if w==v: break res.append(comp) for u in list(adj): if u not in indices: strong(u) return res import random random.seed(42) for trial in range(200): n=random.randint(1,40) adj={i:[] for i in range(n)} for i in range(n): for j in range(n): if random.random()<0.25: adj[i].append(j) a=sorted(sorted(c) for c in scc(adj)) b=sorted(sorted(c) for c in tarjan_recursive(adj)) assert a==b, (a,b) print("ALL 200 RANDOM TRIALS PASSED") # big graph no recursion N=200000 adj={i:[i+1] for i in range(N-1)} adj[N-1]=[0] r=scc(adj) assert len(r)==1 and len(r[0])==N print("BIG CYCLE OK", len(r[0]))