模板 转自https://blog.youkuaiyun.com/nothi/article/details/7739741
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int maxn=110000;//顶点个数
const int maxm=210000;//边个数
const int GRAY = 0;
const int WHITE =-1;
const int BLACK = 1;
typedef struct Edge
{
int s,e,next;
}Edge;
typedef struct Adj{
int edge_sum;
int head[maxn];
Edge edge[maxn];
void init()
{
edge_sum=0;
memset(head,-1,sizeof(head));
}
void add_edge(int a,int b){
edge[edge_sum].s=a;
edge[edge_sum].e=b;;
edge[edge_sum].next=edge_sum;
head[a]=edge_sum++;
}
}Adj;
typedef struct Tarjan{
int n;
int *head;
Adj *adj;
Edge *edge;
int cnt,top,cur;
int dfn[maxn];
int low[maxn];
int stack[maxn];
int belong[maxn];
void initial(Adj *_adj,int _n){
n=_n;
adj=_adj;
head=(*adj).head;
edge=(*adj).edge;
}
void solve()
{
memset(dfn,-1,sizeof(dfn));
memset(color,WHITE,sizeof(color));
top=cnt=top=0;
for(int i=0;i<n;i++)
{
if(color[i]==WHITE)
Tarjan(i);
}
}
void Tarjan(int i)
{
int j=head[i];
color[i]=GRAY;
stack[top++]=i;
dfn[i]=low[i]=++cnt;
while(j!=-1)
{
int u=edge[j].e;
if(color[u]==WHITE)
{
Tarjan(u);
low[i]=min(low[i],low[u]);
}
else if(color[u]==GRAY)
{
low[i]=min(low[i],dfn[u]);
}
j=edge[j].next;
}
color[i]=BLACK;
if(low[i]==dfn[i])
{
do{
j=stack[top--];
belong[j]=cnt;
}while(i!=j)
}
++cnt;
}
}