Kosaraju’s Algorithm in C++
In this post, we will see the implementation of Kosaraju’s Algorithm in C++.
What is Kosaraju’s Algorithm?
Kosaraju’s Algorithm is a classic algorithm used for finding strongly connected components (SCCs) in a directed graph. An SCC is a maximal subgraph where every vertex is reachable from every other vertex in the subgraph. This algorithm is widely used in various applications such as finding cycles in a graph, circuit design, and network analysis.
Below is an example of a strongly connected graph:

How does Kosaraju’s Algorithm Work in C++?
The algorithm works in two main phases:
- Perform a Depth-First Search (DFS) on the original graph and store the vertices in a stack according to their finish times.
- Transpose (reverse) the graph and perform DFS using the vertices in the order defined by the stack to identify the SCCs.
Steps of Kosaraju’s Algorithm to Implement in C++
Following are steps of Kosaraju’s DFS-based simple algorithm that does two DFS traversals of the graph:
- Initialize all vertices as not visited.
- Do a DFS traversal of graph starting from any arbitrary vertex v. If DFS traversal doesn’t visit all vertices, then return false.
- Reverse all arcs (or find transpose or reverse of graph)
- Mark all vertices as not-visited in reversed graph.
- Do a DFS traversal of reversed graph starting from same vertex v (Same as step 2). If DFS traversal doesn’t visit all vertices, then return false. Otherwise return true.
C++ Program to Implement Kosaraju’s Algorithm
Below is a C++ program that implements Kosaraju’s Algorithm for finding strongly connected components:
// C++ program to implement Kosaraju’s algorithm to check if
// a given directed graph is strongly connected or not
#include <iostream>
#include <list>
#include <stack>
using namespace std;
class Graph {
// No. of vertices
int V;
// An array of adjacency lists
list<int>* adj;
// A recursive function to print DFS
// starting from v
void DFSUtil(int v, bool visited[]);
public:
// Constructor and Destructor
Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
~Graph() { delete[] adj; }
// Method to add an edge
void addEdge(int v, int w);
// The main function that returns true if the
// graph is strongly connected, otherwise false
bool isSC();
// Function that returns reverse (or transpose)
// of this graph
Graph getTranspose();
};
// A recursive function to print DFS starting from v
void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and print it
visited[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i, visited);
}
// Function that returns reverse (or transpose) of this
// graph
Graph Graph::getTranspose()
{
Graph g(V);
for (int v = 0; v < V; v++) {
// Recur for all the vertices adjacent to this
// vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i) {
g.adj[*i].push_back(v);
}
}
return g;
}
void Graph::addEdge(int v, int w)
{
// Add w to v’s list.
adj[v].push_back(w);
}
// The main function that returns true if graph
// is strongly connected
bool Graph::isSC()
{
// St1p 1: Mark all the vertices as not visited
// (For first DFS)
bool visited[V];
for (int i = 0; i < V; i++)
visited[i] = false;
// Step 2: Do DFS traversal starting from first vertex.
DFSUtil(0, visited);
// If DFS traversal doesn’t visit all vertices,
// then return false.
for (int i = 0; i < V; i++)
if (visited[i] == false)
return false;
// Step 3: Create a reversed graph
Graph gr = getTranspose();
// Step 4: Mark all the vertices as not visited
// (For second DFS)
for (int i = 0; i < V; i++)
visited[i] = false;
// Step 5: Do DFS for reversed graph starting from
// first vertex. Starting Vertex must be same starting
// point of first DFS
gr.DFSUtil(0, visited);
// If all vertices are not visited in second DFS, then
// return false
for (int i = 0; i < V; i++)
if (visited[i] == false)
return false;
return true;
}
int main()
{
// Create graphs given in the above diagrams
Graph g1(5);
g1.addEdge(0, 1);
g1.addEdge(1, 2);
g1.addEdge(2, 3);
g1.addEdge(3, 0);
g1.addEdge(2, 4);
g1.addEdge(4, 2);
g1.isSC() ? cout << "Yes\n" : cout << "No\n";
Graph g2(4);
g2.addEdge(0, 1);
g2.addEdge(1, 2);
g2.addEdge(2, 3);
g2.isSC() ? cout << "Yes\n" : cout << "No\n";
return 0;
}
Output
Yes No
Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges. Each vertex and edge is processed exactly once in both DFS traversals.
Auxiliary Space: O(V) for storing the visited array and stack.
Note: The above approach requires two traversals of graph. We can find whether a graph is strongly connected or not in one traversal using Tarjan’s Algorithm to find Strongly Connected Components.