1. Pairwise Reachability Check (All-Pairs Reachability)
Intuition
Two vertices u and v belong to the same SCC if and only if there is a directed path from u to v AND a directed path from v to u. For every pair of vertices, check mutual reachability using DFS. Group mutually reachable vertices into equivalence classes.
Algorithm
- Initialize a 2D boolean reachability matrix
canReach[V][V]to false. - For each vertex u from 0 to V - 1:
- Run DFS/BFS from u on the graph to populate
canReach[u][v] = truefor all reachable v. - Initialize
visitedarray of size V with false. - Initialize
sccCount = 0. - For i = 0 to V - 1:
- If
!visited[i]: -
sccCount++ - For j = 0 to V - 1:
- If
canReach[i][j] && canReach[j][i]: -
visited[j] = true - Return
sccCount.
#include <iostream>#include <vector> void dfsReach(int u, int start, const std::vector<std::vector<int>>& adj, std::vector<std::vector<bool>>& reach) { reach[start][u] = true; for (int v : adj[u]) { if (!reach[start][v]) { dfsReach(v, start, adj, reach); } }} int countSCCBrute(int V, const std::vector<std::vector<int>>& adj) { std::vector<std::vector<bool>> reach(V, std::vector<bool>(V, false)); for (int i = 0; i < V; ++i) { dfsReach(i, i, adj, reach); } std::vector<bool> visited(V, false); int sccCount = 0; for (int i = 0; i < V; ++i) { if (!visited[i]) { sccCount++; for (int j = 0; j < V; ++j) { if (reach[i][j] && reach[j][i]) { visited[j] = true; } } } } return sccCount;} int main() { int V = 5; std::vector<std::vector<int>> adj = {{2, 3}, {0}, {1}, {4}, {}}; std::cout << "SCC Count (Brute): " << countSCCBrute(V, adj) << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(V * (V + E)) because running DFS from all V vertices takes V * (V + E), followed by V^2 grouping. - Space complexity:
O(V^2) to store the pairwise reachability matrix.