Skip to content

Commit 6e55266

Browse files
authored
Merge pull request #632 from PranathiNagisetti/kosaraju_algo
Add Kosaraju's Algorithm for SCC in Python graph algorithms
2 parents 0716a8c + d5c7482 commit 6e55266

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
""""
2+
Kosaraju’s Algorithm
3+
Description:Finds all Strongly Connected Components (SCCs) in a directed graph.
4+
Time Complexity: O(V + E)
5+
Space Complexity: O(V + E)
6+
"""
7+
8+
from collections import defaultdict
9+
10+
class Graph:
11+
def __init__(self, vertices):
12+
self.V = vertices
13+
self.graph = defaultdict(list)
14+
15+
# Add an edge from u to v
16+
def add_edge(self, u, v):
17+
self.graph[u].append(v)
18+
19+
# DFS utility
20+
def _dfs(self, v, visited, component):
21+
visited[v] = True
22+
component.append(v)
23+
for neighbor in self.graph[v]:
24+
if not visited[neighbor]:
25+
self._dfs(neighbor, visited, component)
26+
27+
# Transpose the graph
28+
def _transpose(self):
29+
g_t = Graph(self.V)
30+
for v in self.graph:
31+
for u in self.graph[v]:
32+
g_t.add_edge(u, v)
33+
return g_t
34+
35+
# Kosaraju's Algorithm to find SCCs
36+
def kosaraju_scc(self):
37+
visited = [False] * self.V
38+
stack = []
39+
40+
# Step 1: Fill vertices in stack according to finishing times
41+
for i in range(self.V):
42+
if not visited[i]:
43+
self._fill_order(i, visited, stack)
44+
45+
# Step 2: Transpose the graph
46+
transposed = self._transpose()
47+
48+
# Step 3: Process all vertices in order defined by stack
49+
visited = [False] * self.V
50+
sccs = []
51+
while stack:
52+
v = stack.pop()
53+
if not visited[v]:
54+
component = []
55+
transposed._dfs(v, visited, component)
56+
sccs.append(component)
57+
58+
return sccs
59+
60+
# Helper function for first DFS to fill stack
61+
def _fill_order(self, v, visited, stack):
62+
visited[v] = True
63+
for neighbor in self.graph[v]:
64+
if not visited[neighbor]:
65+
self._fill_order(neighbor, visited, stack)
66+
stack.append(v)
67+
68+
# test Cases
69+
if __name__ == "__main__":
70+
g = Graph(5)
71+
g.add_edge(1, 0)
72+
g.add_edge(0, 2)
73+
g.add_edge(2, 1)
74+
g.add_edge(0, 3)
75+
g.add_edge(3, 4)
76+
77+
print("Strongly Connected Components:")
78+
sccs = g.kosaraju_scc()
79+
for i, component in enumerate(sccs, 1):
80+
print(f"Component {i}: {component}")
81+

0 commit comments

Comments
 (0)