有向图强连通分量的Tarjan算法
vector <int> G[maxn];
int pre[maxn];
int low[maxn];
int sccno[maxn];
int dfs_clock;
int scc_cnt;
stack <int> S;
int n, m;
int degree[maxn];
int cnt[maxn];
void dfs(int u)
{
pre[u] = low[u] = ++dfs_clock;
S.push(u);
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(!pre[v])
{
dfs(v);
low[u] = min(low[u], low[v]);
}
else if(!sccno[v])
low[u] = min(low[u], pre[v]);
}
if(pre[u] == low[u])
{
scc_cnt++;
while(1)
{
cnt[scc_cnt]++;
int x = S.top();
S.pop();
sccno[x] = scc_cnt;
if(x == u)
break;
}
}
}
void find_scc()
{
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i);
}