Implementation of Kosaraju's Algorithm
Explore how to implement splitting a graph into its strongly connected components.
We'll cover the following...
Implementing SCC identification
Our implementation of Kosaraju’s algorithm uses similar building blocks as our topological sort implementation. The setup of the class is similar, again using the adjacency list graph representation.
We’ve also borrowed the dfs routine from the topological sort class, which keeps track of the node finishing order during DFS. The main work will be done in the yet unfinished computeScc function (line 21). The variable scc (line 14) will be used to store the strongly connected components while they compute. Each SCC is represented as a vector<int> of the nodes it contains, and in total, all SCCs form a vector<vector<int>>.
Let’s start implementing computeScc. First, we need to run the forward pass DFS.
This is a straightforward DFS from all starting nodes. In the end, we’ll obtain the reverse finishing order for the backward DFS. We now have to do some bookkeeping before we run the backward DFS.
fill(this->nodeStates.begin(), this->nodeStates.end(), NodeState::UNVISITED);
this->finishOrder.clear();
this->transpose();
Here, we’ll reset all nodes to be unvisited and clear the finishOrder vector populated by the dfs. we’ll use it during the backward pass to store the newly discovered SCC. We’ll also call the transpose function to reverse all edges. Its implementation looks like this:
In ...