const int maxn=100050;
int inStack[maxn],dfn[maxn],low[maxn],Index;
int inComponent[maxn],componentDegree[maxn],componentNum=0;
vector<int>edge[maxn],component[maxn];
stack<int>Stack;
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
void tarjan(int i){
int j;
dfn[i]=low[i]=Index++;//dfn为当前访问次序,low为所能追溯到的最早次序
inStack[i]=true;
Stack.push(i);
for(int e=0;e<edge[i].size();e++){
j=edge[i][e];
if(dfn[j]==0){//如果j没有访问过
tarjan(j);
low[i]=min(low[i],low[j]);
}
else if(inStack[j])//如果j已经在栈中,则更新low值
low[i]=min(low[i],dfn[j]);
}
if(dfn[i]==low[i]){//当前访问次序与最早次序相同说明形成了强连通分量
componentNum++;//记录强连通分量个数
do{
j=Stack.top();
Stack.pop();
inStack[j]=false;
component[componentNum].push_back(j);
inComponent[j]=componentNum;//记录j属于哪个强连通分量
}
while(j!=i);
}
}