0% found this document useful (0 votes)
19 views5 pages

Kosaraju's Algorithm

Kosaraju's Algorithm is used to find Strongly Connected Components (SCCs) in directed graphs through a two-pass DFS approach. The algorithm involves performing a DFS to compute finishing times, transposing the graph, and then performing a second DFS on the transposed graph to identify SCCs. It has a time complexity of O(V + E) and is beneficial for applications like dependency resolution and analyzing connectivity in networks.

Uploaded by

stringkartik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views5 pages

Kosaraju's Algorithm

Kosaraju's Algorithm is used to find Strongly Connected Components (SCCs) in directed graphs through a two-pass DFS approach. The algorithm involves performing a DFS to compute finishing times, transposing the graph, and then performing a second DFS on the transposed graph to identify SCCs. It has a time complexity of O(V + E) and is beneficial for applications like dependency resolution and analyzing connectivity in networks.

Uploaded by

stringkartik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

9.

Kosaraju's Algorithm
What is an SCC?

A Strongly Connected Component (SCC) is a subgraph where:


Every vertex is reachable from every other vertex within the same SCC.

Key Insights

1. A directed graph and its transpose graph (reversing all edges) have the same SCCs.
2. The finishing times of nodes in the first DFS help us explore SCCs in the transpose graph in
reverse order.

Steps

1. First DFS:
Perform DFS to compute the finishing times of nodes.
Push nodes onto a stack in the order of completion.
2. Transpose the Graph:
Reverse the direction of all edges.
3. Second DFS:
Pop nodes from the stack.
Perform DFS on the transpose graph, visiting nodes in the stack order.
Each DFS traversal corresponds to one SCC.

Algorithm Components

1. Stack:
Maintains nodes by their finishing times during the first DFS.
2. Transpose Graph:
Reverses all edges of the original graph.
Pseudocode

1. Initialize:
- Stack to store finishing times.
- Visited array to track visited nodes.

2. First DFS (on original graph):


- For each unvisited node:
- Perform DFS.
- Push nodes onto the stack as they finish.

3. Transpose the graph:


- Reverse all edges of the original graph.

4. Second DFS (on transpose graph):


- Pop nodes from the stack.
- For each unvisited node:
- Perform DFS on the transpose graph.
- Collect all nodes visited in this DFS as one SCC.

5. Output all SCCs.

C++ Implementation

// Function to perform DFS and store nodes in the stack by finishing time
void dfs(int node, vector<vector<int>>& adj, vector<int>& visited, stack<int>&
st) {
visited[node] = 1;
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
dfs(neighbor, adj, visited, st);
}
}
st.push(node);
}

// Function to perform DFS on the transposed graph and find SCCs


void reverseDFS(int node, vector<vector<int>>& transpose, vector<int>&
visited, vector<int>& scc) {
visited[node] = 1;
scc.push_back(node);
for (int neighbor : transpose[node]) {
if (!visited[neighbor]) {
reverseDFS(neighbor, transpose, visited, scc);
}
}
}

// Function to find all Strongly Connected Components (SCCs) using Kosaraju's


Algorithm
vector<vector<int>> findSCCs(int V, vector<vector<int>>& edges) {
vector<vector<int>> adj(V), transpose(V);
// Create adjacency list for the original graph
for (auto& edge : edges) {
adj[edge[0]].push_back(edge[1]);
}
// Step 1: Perform DFS to get nodes in finishing time order
stack<int> st;
vector<int> visited(V, 0);
for (int i = 0; i < V; i++) {
if (!visited[i]) {
dfs(i, adj, visited, st);
}
}
// Step 2: Transpose the graph
for (int i = 0; i < V; i++) {
for (int neighbor : adj[i]) {
transpose[neighbor].push_back(i);
}
}
// Step 3: Perform DFS on the transposed graph
fill(visited.begin(), visited.end(), 0);
vector<vector<int>> sccs;
while (!st.empty()) {
int node = st.top();
st.pop();
if (!visited[node]) {
vector<int> scc;
reverseDFS(node, transpose, visited, scc);
sccs.push_back(scc);
}
}
return sccs;
}

int main() {
int V = 5;
vector<vector<int>> edges = {{0, 1}, {1, 2}, {2, 0}, {1, 3}, {3, 4}};
vector<vector<int>> sccs = findSCCs(V, edges);

cout << "Strongly Connected Components:" << endl;


for (auto& scc : sccs) {
for (int node : scc) {
cout << node << " ";
}
cout << endl;
}

return 0;
}

Example

Input Graph:

Vertices: 5
Edges: {(0,1),(1,2),(2,0),(1,3),(3,4)}{ (0,1), (1,2), (2,0), (1,3), (3,4) }

Output:

Strongly Connected Components:


0 2 1
3
4

Time Complexity

1. First DFS: O(V + E)


2. Transpose Graph: O(V + E)
3. Second DFS: O(V + E)
4. Overall: O(V + E)

Space Complexity

Adjacency List: O(V + E)


Stack and Visited Array: O(V)
Total: O(V + E)

Comparison: Kosaraju vs. Tarjan

Feature Kosaraju Tarjan


Approach Two-pass DFS Single-pass DFS
Time Complexity O(V + E) O(V + E)
Space Complexity O(V + E) O(V + E)
Ease of Implementation Requires graph transpose No transpose needed

Why Use Kosaraju?


1. Intuitive Approach:
Clear separation of graph traversal and SCC identification.
2. Applications:
Dependency resolution.
Analyzing connectivity in social networks.

When to Prefer Tarjan?


If memory usage is a concern (avoids explicit graph transposition).

You might also like