重邊的判斷模式
void tarjan(int u,int pre)
{
low[u] = dfn[u] = ++d_cnt; mys.push(u);
int flag=0;
for(int i=head[u]; i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else
{
if(v==pre)
{
if(flag) low[u]=min(low[u],dfn[v]); //重邊
flag++;
}
else low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
s_cnt++;
while(1)
{
int x=mys.top(); mys.pop();
scc[x]=s_cnt;
if(x==u) break;
}
}
}
void dfs(int u)
{
dfn[u] = low[u]= ++d_cnt;
mys.push(u); vis[u]=1;
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
s_cnt++;
while(1)
{
int x=mys.top(); mys.pop();
num[s_cnt]++;
scc[x]=s_cnt;
vis[x]=0;
if(x==u) break;
}
}
}