COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython example pack ↓

Graphs and paths · 27 / 53

Topological sorting, Tarjan and Kosaraju

Understand → trace → implement → justify

1 min reading · allow extra time for practice

A topological order of a DAG places u beforev for every u→v edge. Kahn removes zero-indegree vertices; producing fewer thanV vertices proves a cycle. Orders need not be unique. Build dependencies and prerequisites are natural applications.

An SCC is a maximal set of mutually reachable vertices. Contracting SCCs forms a DAG. Kosaraju uses finishing order and then reversed finishing order on the transposed graph; arbitrary second-pass order is incorrect.

Tarjan maintains DFS indices, low links and an active stack. Edges into already completed SCCs must not incorrectly lower low links. When low[u]==index[u], pop one component. Bridge/articulation low-link rules solve different problems and should not be copied blindly.

A worked trace

A↔B, B→C, C↔D has SCCs {A,B} and{C,D}; condensation is a directed two-node DAG.

Cost and assumptions

Kahn, Tarjan and Kosaraju use O(V+E) time and O(V) stack/metadata with adjacency lists.

Executable example

Run with Python 3. Assertions check a small example; they do not constitute a general correctness proof. Some advanced examples are explicitly small models or reference oracles, not full production implementations.

Python 3
from collections import deque

def topo(g):
    degree = {u: 0 for u in g}
    for u in g:
        for v in g[u]: degree[v] += 1
    q, out = deque(u for u in g if degree[u] == 0), []
    while q:
        u = q.popleft(); out.append(u)
        for v in g[u]:
            degree[v] -= 1
            if degree[v] == 0: q.append(v)
    if len(out) != len(g): raise ValueError("cycle")
    return out
assert topo({"A":["B"],"B":[]}) == ["A","B"]

TEST YOUR UNDERSTANDING

Your turn

Does finding SCCs topologically sort a cyclic graph?

Reveal the reasoning

The original cyclic graph has no topological order. Sort the condensation DAG and handle internal cycles separately.

Take it further

  1. Write down the input contract and the invariant before changing the example.
  2. Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
  3. Derive the cost under the stated model; measure several input sizes and explain discrepancies.

Primary reading & lecture notes

Original explanations in this course; these references provide proofs and further reading. Source links may cover the broader module.

Jeff Erickson · Algorithms ↗
Solve the exercise before moving on.