补一年前的坑。
有向图强连通分量
inline void tarjan(int x){
dfn[x]=low[x]=++dt,sta[++tp]=x,ins[x]=1;
forg(i,x)
if(!dfn[to[i]])tarjan(to[i]),low[x]=min(low[x],low[to[i]]);
else if(ins[to[i]])low[x]=min(low[x],dfn[to[i]]);
if(dfn[x]==low[x]){
++bn;int y;
do y=sta[tp--],ins[y]=0,bel[y]=bn;
while(x!=y);
}
}
low数组啥意思我也说不清,大概理解成一个辅助数组吧。。这个算法的妙处就在于,一个强联通分量的所有点,都会在标号最小的那个点那里被统计到。
无向图边双
inline void tarjan(int x,int e){
dfn[x]=low[x]=++dt;
forg(i,x)if(!dfn[to[i]]){
tarjan(to[i],i),low[x]=min(low[x],low[to[i]]);
if(low[to[i]]>dfn[x])br[i]=br[i^1]=1;
}else if(i!=(e^1))low[x]=min(low[x],low[to[i]]);
}
无向图点双
inline void tarjan(int x){
dfn[x]=low[x]=++dt;
int c=0;
forg(i,x)if(!dfn[to[i]]){
tarjan(to[i]);low[x]=min(low[x],low[to[i]]);
if(low[to[i]]>=dfn[x]){
++c;if(x!=rt||c>1)cut[x]=1;
}
}else low[x]=min(low[x],dfn[to[i]]);
}
比有向图简单多了。