The idea

DFS assigns discovery time. Low-link = min reachable discovery time. Root of SCC has low-link = discovery time.

Advertisement

Implementation

int[] disc, low;
Deque stack;
boolean[] onStack;
int time;
List> sccs = new ArrayList<>();

void dfs(int u) {
  disc[u] = low[u] = time++;
  stack.push(u); onStack[u] = true;
  for (int v : graph[u]) {
    if (disc[v] == -1) { dfs(v); low[u] = min(low[u], low[v]); }
    else if (onStack[v]) low[u] = min(low[u], disc[v]);
  }
  if (low[u] == disc[u]) {
    List scc = new ArrayList<>();
    while (true) {
      int v = stack.pop(); onStack[v] = false; scc.add(v);
      if (v == u) break;
    }
    sccs.add(scc);
  }
}
Advertisement

Complexity

O(V + E). One DFS.

Kosaraju&amp;amp;#x27;s alternative

Two DFSes: on graph + reversed graph. Simpler to understand, same complexity.