const int maxn=1e5+7;
int Stack[maxn], low[maxn], dfn[maxn], inStack[maxn], belong[maxn];
int now, cnt; // now:时间戳,cnt强连通的个数
struct edge{
int v,nex;
}edges[maxn*5];
int head[maxn],edge_cnt;
void addedge(int u,int v){
edges[++cnt]=(edge){v,head[u]};
head[u]=cnt;
}
stack<int> s;
void init() {
now = cnt = 0;
memset(inStack, 0,sizeof(inStack));
memset(belong, 0,sizeof(belong));
memset(dfn, 0,sizeof(dfn));
memset(low, 0,sizeof(low));
}
void tarjan(int u) {
// 打上标记,入栈
low[u] = dfn[u] = ++now;
s.push(u);
inStack[u] = 1;
for (int i = head[u]; i!=-1; i=edges[i].nex) {
int v = edges[i].v;
if (!dfn[v]) { //未访问过
tarjan(v);
low[u] = min(low[u], low[v]); //low,dfn(v)中可能是最小的
}
else if (inStack[v]) { //访问过,还在栈中
low[u] = min(low[u], dfn[v]); //dfn (v)中找最小
}
}
// 回溯,如果当前节点的dfn = low 表示栈中形成一个强连通分量
if (dfn[u] == low[u]) {
++cnt; // 统计个数
int v=-1;
while (v!= u) {
v = s.top();
s.pop();
belong[v] = cnt;
inStack[v] = 0;
}
}
}