Kosaraju's Algorithm

Graph Selection

Playback Controls

Select a graph to begin SCC detection

Kosaraju's Info

Key Features:

  • • Finds strongly connected components
  • • Two-pass DFS algorithm
  • • Time complexity: O(V + E)
  • • Uses graph transposition
  • • Linear time solution

Legend:

Current (Pass 1)
Current (Pass 2)
SCC Found
Processing

Reference implementation of Kosaraju's Algorithm. Select a language tab to view and copy the code.

def kosaraju(adj: list[list[int]]) -> int:
    n       = len(adj)
    visited = [False] * n
    order   = []

    def dfs1(v: int) -> None:
        visited[v] = True
        for u in adj[v]:
            if not visited[u]: dfs1(u)
        order.append(v)

    for i in range(n):
        if not visited[i]: dfs1(i)

    # Build reversed graph
    radj = [[] for _ in range(n)]
    for u in range(n):
        for v in adj[u]: radj[v].append(u)

    visited[:] = [False] * n
    comp = [-1] * n; num_scc = 0

    def dfs2(v: int, scc_id: int) -> None:
        visited[v] = True; comp[v] = scc_id
        for u in radj[v]:
            if not visited[u]: dfs2(u, scc_id)

    for v in reversed(order):
        if not visited[v]:
            dfs2(v, num_scc); num_scc += 1

    return num_scc

Python — Code Walkthrough

  1. order.append(v) after recursion — finish order

    order.append(v)

    Appending v after recursing into all neighbors records the finish order. Reversed, this gives the source-SCC-first order needed for Pass 2.

  2. List comprehension for reversed graph

    radj = [[] for _ in range(n)]

    Creates n empty adjacency lists. The edge reversal loop then fills them. The list comprehension is more Pythonic than repeated list.append calls.

  3. visited[:] = [...] — in-place reset

    visited[:] = [False] * n

    The slice assignment [:] modifies the existing list in-place. If dfs1 captured visited via closure, a plain reassignment (visited = [...]) would create a new object — the closure would not see it.

  4. reversed(order) for Pass 2

    for v in reversed(order)

    reversed() iterates in-place without copying the list. Processing vertices in reverse finish order ensures SCCs are discovered correctly in Pass 2.