记录一个板子
int e[N], ne[N], h[N], cnt;
int stk[N], top;
int dfn[N], low[N], timestamp;
int id[N], scc_cnt;
bool in_stk[N];
void tarjan(int u)
{
stk[++top] = u;
in_stk[u] = true;
dfn[u] = low[u] = ++timestamp;
for (int i = h[u]; ~i;i=ne[i])
{
int j = e[i];
if(!dfn[j]){
tarjan(j);
low[u] = min(low[u], low[j]);
}
else if(in_stk[j]){//防止用其他拓扑序更靠前的强连通分量的点更新掉当前节点的low
low[u] = min(low[u], dfn[j]);
}
}
if(dfn[u]==low[u])
{
int y;
++scc_cnt;
do{
y = stk[top--];
in_stk[y] = false;
id[y] = scc_cnt;
} while (u != y);
}
}