#include<bits/stdc++.h> #define ll long long struct Tarjan // find all strongly connected components of a directed graph { // NOTE: // vertex-index can be either 0-BASED or 1-BASED // edge is ONE-WAY // return all Strongly-Connected-Components with length >= 2 int n; // number of vertice vector< vector<int> > adj; int *num; int *low; int *visited; int cnt; vector< vector<int> > sccs; stack<int> stk; void init(int n_) { n = n_; adj.resize(0); adj.resize(n+1); num = new int[n+1]; low = new int[n+1]; visited = new int[n+1]; } void addEdge(int u, int v) { adj[u].push_back(v); } void dfs_scc(int u) { num[u] = low[u] = ++cnt; stk.push(u); for (int v : adj[u]) { if (!visited[v]) { if (num[v] < 0) { dfs_scc(v); low[u] = min(low[u], low[v]); } else { low[u] = min(low[u], num[v]); } } } if (num[u] == low[u]) { vector<int> scc; while (true) { int top = stk.top(); stk.pop(); scc.push_back(top); visited[top] = 1; if (top == u) break; } sccs.push_back(scc); } } vector< vector<int> >findSCC() { sccs.clear(); while(!stk.empty()) stk.pop(); cnt = 0; for (int i = 0; i <= n; ++i) { num[i] = -1; low[i] = -1; visited[i] = 0; } for (int i = 0; i <= n; ++i) if (!visited[i]) dfs_scc(i); return sccs; } };