import java.util.*; import java.util.stream.Stream; // optimized version of https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm public class SCCTarjan { List[] graph; boolean[] visited; Stack stack; int time; int[] lowlink; List> components; public List> scc(List[] graph) { int n = graph.length; this.graph = graph; visited = new boolean[n]; stack = new Stack<>(); time = 0; lowlink = new int[n]; components = new ArrayList<>(); for (int u = 0; u < n; u++) if (!visited[u]) dfs(u); return components; } void dfs(int u) { lowlink[u] = time++; visited[u] = true; stack.add(u); boolean isComponentRoot = true; for (int v : graph[u]) { if (!visited[v]) dfs(v); if (lowlink[u] > lowlink[v]) { lowlink[u] = lowlink[v]; isComponentRoot = false; } } if (isComponentRoot) { List component = new ArrayList<>(); while (true) { int x = stack.pop(); component.add(x); lowlink[x] = Integer.MAX_VALUE; if (x == u) break; } components.add(component); } } // Usage example public static void main(String[] args) { List[] g = Stream.generate(ArrayList::new).limit(3).toArray(List[]::new); g[2].add(0); g[2].add(1); g[0].add(1); g[1].add(0); List> components = new SCCTarjan().scc(g); System.out.println(components); } }