void dfs(int node, vector<int> &vis, vector<int> adj[], stack<int> &st) {
vis[node] = 1;
for (auto it : adj[node]) {
if (!vis[it]) dfs(it, vis, adj, st);
}
st.push(node);
}
void dfs3(int node, vector<int> &vis, vector<int> adjT[], vector<int> &comp) {
vis[node] = 1;
comp.push_back(node);
for (auto it : adjT[node]) {
if (!vis[it]) dfs3(it, vis, adjT, comp);
}
}
// Returns {number of SCCs, components}
pair<int, vector<vector<int>>> kosaraju(int V, vector<int> adj[]) {
vector<int> vis(V, 0);
stack<int> st;
for (int i = 0; i < V; i++)
if (!vis[i]) dfs(i, vis, adj, st);
vector<int> adjT[V];
for (int i = 0; i < V; i++) {
vis[i] = 0;
for (auto it : adj[i]) adjT[it].push_back(i);
}
vector<vector<int>> sccs;
int scc_count = 0;
while (!st.empty()) {
int node = st.top();
st.pop();
if (!vis[node]) {
vector<int> comp;
dfs3(node, vis, adjT, comp);
sccs.push_back(comp);
scc_count++;
}
}
return {scc_count, sccs};
}
// Usage:
// auto [count, components] = kosaraju(V, adj);
// count = number of SCCs
// components[i] = nodes in ith SCC