Strongly Connected Components (SCC)
Definition
A Strongly Connected Component (SCC) is a specific group of nodes within a Directed Graph. In this group, you can start at any node and reach every other node in the same group by following the arrows (edges).

How it Works
Think of a directed graph like a city with one-way streets.
- The Rule: If you can drive from House A to House B and figure out a way to drive back from House B to House A, then A and B are in the same Strongly Connected Component.
- The Cycle: SCCs essentially define “cycles” or loops in a graph. If you can leave a group but never return, you have crossed into a different component.
- Partition: Every node in a directed graph belongs to exactly one SCC.
Real-World Analogy
City Neighborhoods:
Imagine a city divided into neighborhoods by highways.
- Inside a neighborhood (The SCC): The streets are a maze of one-way roads, but if you know the way, you can eventually get from any house to any other house within that neighborhood.
- Between neighborhoods: Once you take the highway exit to go to the “North Side,” you might not be able to come back to the “South Side” because the highway only goes one way. The “South Side” is one SCC, and the “North Side” is another.
Example
Graph:
- A rightarrow B
- B rightarrow C
- C rightarrow A (This creates a loop: A-B-C-A)
- B rightarrow D (One way street to D)
Components:
- {A, B, C}: You can travel between all of them.
- {D}: Once you are at D, you cannot go back to A, B, or C. D is its own component.
Code Example (Kosaraju’s Algorithm)
Note: This algorithm uses two passes of DFS to find these groups.
from collections import defaultdict
class Graph:
def __init__(self, vertices):
self.V = vertices
self.graph = defaultdict(list)
def add_edge(self, u, v):
self.graph[u].append(v)
# Step 1: Fill stack based on finishing time (DFS)
def fill_order(self, v, visited, stack):
visited.add(v)
for i in self.graph[v]:
if i not in visited:
self.fill_order(i, visited, stack)
stack.append(v)
# Step 2: Transpose the graph (Reverse all edges)
def get_transpose(self):
g = Graph(self.V)
for i in self.graph:
for j in self.graph[i]:
g.add_edge(j, i)
return g
# Step 3: DFS on reversed graph
def dfs_print(self, v, visited):
visited.add(v)
print(v, end=" ")
for i in self.graph[v]:
if i not in visited:
self.dfs_print(i, visited)
def print_sccs(self):
stack = []
visited = set()
# 1. Fill stack with vertices by finish time
for i in range(self.V):
if i not in visited:
self.fill_order(i, visited, stack)
# 2. Reverse the graph
gr = self.get_transpose()
# 3. Process nodes in stack order
visited.clear()
while stack:
i = stack.pop()
if i not in visited:
gr.dfs_print(i, visited)
print("") # New line for new component
# Usage
g = Graph(5)
g.add_edge(1, 0)
g.add_edge(0, 2)
g.add_edge(2, 1) # Cycle 0-1-2
g.add_edge(0, 3)
g.add_edge(3, 4)
print("Strongly Connected Components:")
g.print_sccs()
# Output:
# 0 1 2 (Order may vary)
# 3
# 4
Complexity Analysis
- Time Complexity: O(V + E). We traverse the graph (DFS) twice and reverse it once. All are linear operations.
- Space Complexity: O(V). We need arrays to store visited status and the stack.
Use Cases
- Social Media Analysis: Finding tight-knit communities where everyone follows everyone else.
- Web Crawlers: Identifying “link farms” or groups of websites that link to each other to boost SEO rankings artificially.