Graph Theory
Strongly Connected Components
Algorithms
Computer Science
Network Analysis

How to find Strongly Connected Components in a Graph?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Strongly connected components, or SCCs, are maximal groups of vertices in a directed graph where every node can reach every other node in the same group. SCC decomposition is useful in dependency analysis, deadlock detection, compiler optimization, and service graph diagnostics. This guide explains two standard linear-time algorithms, Kosaraju and Tarjan, with runnable Python examples.

Build Intuition for SCCs

Think of SCCs as mutual reachability islands. If you collapse each SCC into one node, the resulting graph is a directed acyclic graph. That condensed graph gives a high-level dependency order.

Example intuition:

  • If service A calls B, B calls C, and C calls A, those three form one SCC.
  • Any scheduling logic that ignores this cycle can produce unstable rollout order.

A graph is usually represented as adjacency lists.

python
1graph = {
2    0: [1],
3    1: [2, 3],
4    2: [0],
5    3: [4],
6    4: [5],
7    5: [3],
8}

Kosaraju Algorithm

Kosaraju performs two DFS passes.

Steps:

  1. DFS on original graph and push vertices by finish time.
  2. Reverse all edges.
  3. DFS on reversed graph in reverse finish order.
  4. Each DFS tree from step three is one SCC.
python
1from collections import defaultdict
2
3
4def kosaraju_scc(graph):
5    visited = set()
6    finish_order = []
7
8    all_nodes = set(graph.keys())
9    for u in graph:
10        for v in graph[u]:
11            all_nodes.add(v)
12
13    for u in all_nodes:
14        graph.setdefault(u, [])
15
16    def dfs1(u):
17        visited.add(u)
18        for v in graph[u]:
19            if v not in visited:
20                dfs1(v)
21        finish_order.append(u)
22
23    for u in all_nodes:
24        if u not in visited:
25            dfs1(u)
26
27    reversed_graph = defaultdict(list)
28    for u in graph:
29        for v in graph[u]:
30            reversed_graph[v].append(u)
31
32    visited.clear()
33    components = []
34
35    def dfs2(u, bucket):
36        visited.add(u)
37        bucket.append(u)
38        for v in reversed_graph[u]:
39            if v not in visited:
40                dfs2(v, bucket)
41
42    for u in reversed(finish_order):
43        if u not in visited:
44            bucket = []
45            dfs2(u, bucket)
46            components.append(bucket)
47
48    return components
49
50print(kosaraju_scc(graph))

Kosaraju is easy to reason about and often preferred for teaching and debugging.

Tarjan Algorithm

Tarjan finds SCCs in one DFS pass using discovery indices, low-link values, and a stack.

python
1def tarjan_scc(graph):
2    index_counter = 0
3    indices = {}
4    low = {}
5    stack = []
6    on_stack = set()
7    components = []
8
9    all_nodes = set(graph.keys())
10    for u in graph:
11        for v in graph[u]:
12            all_nodes.add(v)
13
14    for u in all_nodes:
15        graph.setdefault(u, [])
16
17    def strongconnect(u):
18        nonlocal index_counter
19        indices[u] = index_counter
20        low[u] = index_counter
21        index_counter += 1
22
23        stack.append(u)
24        on_stack.add(u)
25
26        for v in graph[u]:
27            if v not in indices:
28                strongconnect(v)
29                low[u] = min(low[u], low[v])
30            elif v in on_stack:
31                low[u] = min(low[u], indices[v])
32
33        if low[u] == indices[u]:
34            bucket = []
35            while True:
36                w = stack.pop()
37                on_stack.remove(w)
38                bucket.append(w)
39                if w == u:
40                    break
41            components.append(bucket)
42
43    for u in all_nodes:
44        if u not in indices:
45            strongconnect(u)
46
47    return components
48
49print(tarjan_scc(graph))

Tarjan avoids explicit graph reversal and is efficient in memory-conscious workflows.

Choosing Between Kosaraju and Tarjan

Both are linear in vertices plus edges.

Practical tradeoff:

  • Kosaraju is simpler to explain and inspect step-by-step.
  • Tarjan is single-pass and often preferred in large graph processing systems.

For many applications, code clarity matters more than minor constant-factor differences.

Production Implementation Tips

  • Include nodes that appear only as destination vertices.
  • Do not mutate the graph during traversal.
  • For very deep graphs, consider iterative DFS to avoid recursion depth limits.
  • After SCC extraction, build condensed graph for topological dependency planning.

These details prevent subtle correctness issues in real pipelines.

Common Pitfalls

  • Forgetting target-only vertices that are absent from adjacency keys.
  • Incorrect low-link updates in Tarjan when stack-membership checks are missing.
  • Processing Kosaraju second pass in wrong order.
  • Ignoring isolated vertices and self-loops in tests.
  • Mutating adjacency data while DFS runs.

Summary

  • SCCs partition directed graphs into maximal mutual-reachability groups.
  • Kosaraju uses two DFS passes with a reversed graph.
  • Tarjan uses one DFS pass with index and low-link tracking.
  • Both algorithms run in linear time and scale well.
  • Reliable implementations must handle isolated and target-only nodes explicitly.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.