<code>
void pbc_dfs(int u, int parent) {//求双连通分量中的边
dfn[u] = low[u] = dfn_now++;
foreach e in adjacent list [u] {
v = e->v;
if (v != parent && dfn[v] < dfn[u]) {
stack.push(Edge(u, v));
if (0 != dfn[v])
low[u] = min(low[u], dfn[v]);
else {
pbc_dfs(v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) { // u is a cut point //此处会枚举所有的双连通分量
do {
Edge edg = stack.pop();
...(some operation)
} while(edg is not uv);
++component_id;
}
}
}
}
}
</code>
<code>
int dfn[M],low[M],index;
void tarjan(int u,int parent){
dfn[u]=low[u]=index++;//应当小心index,可能会出现报错的情况
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(dfn[v]!=0&&v!=pa){//如果v为u的父亲的话,那么就没意思了。可以逻辑一下
low[u]=min(low[u],dfn[v]);
}else if(dfn[v]==0){
tarjan(v,u);
low[u]=min(low[v],low[u]);
if(dfn[u]<low[v]){//cout<<" == "<<u<<v<<endl;
match(u,v);
}
}
}
}
void solve(int n){
memset(dfn,0,sizeof(dfn));
memset(fa,-1,sizeof(fa));
index=1;
for(int i=1;i<=n;i++){
if(dfn[i]==0){//可能整张图本身就不连通,而是由多个联通块组成
tarjan(i,-1);
}
}
}
</code>