Tarjan
Độ phức tạp: \(O(N+M)\)
#include <bits/stdc++.h>
using namespace std;
const int NODE = 100000;
const int EDGE = 100000;
int numNode, numEdge;
vector<int> adj[NODE];
int Time, num[NODE], low[NODE];
int numComp, compID[NODE];
stack<int> comp;
void dfs(int u) {
num[u] = low[u] = ++Time;
comp.push(u);
for (int v : adj[u]) if (!compID[v]) {
if (!num[v]) {
dfs(v);
low[u] = min(low[u], low[v]);
}
else {
low[u] = min(low[u], num[v]);
}
}
if (num[u] == low[u]) {
numComp++;
while (true) {
int v = comp.top(); comp.pop();
compID[v] = numComp;
if (v == u) break;
}
}
}
void tarjan() {
memset(num, 0, sizeof num);
memset(low, 0, sizeof low);
memset(compID, 0, sizeof compID);
Time = numComp = 0;
for (int i = 1; i <= numNode; ++i) {
if (!num[i]) dfs(i);
}
}
int main() {
// các đỉnh có chỉ số từ 1 -> numNode
cin >> numNode >> numEdge;
for (int i = 0; i < numEdge; ++i) {
int x, y; cin >> x >> y;
adj[x].push_back(y);
}
tarjan();
cout << numComp << '\n';
for (int i = 1; i <= numNode; ++i) {
cout << i << " -> " << compID[i] << '\n';
}
return 0;
}