tarjan
点击查看代码
//缩点
void tarjan(int u){
dfn[u]=low[u]=++t;
s[++top]=u;vis[u]=1;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);low[u]=min(low[u],low[v]);
}else if(vis[v]) low[u]=min(low[u],low[v]);
}if(dfn[u]==low[u]){
vis[u]=0;
c[++sum]++;fa[u]=sum;
while(s[top]^u){
vis[st[top]]=0;
c[sum]++;fa[s[top--]]=sum;
}--top;
}
}
//割点
void tarjan(int u){
dfn[u]=low[u]=++t;int f=0;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
if(dfn[u]<=low[v]) ++f;
}else low[u]=min(low[u],dfn[v]);
}if((u==rt&&f>1)||(u!=rt&&f)) q.push(u);
}
//割边
void tarjan(int u){
dfn[u]=low[u]=++t;int f=0;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
if(dfn[u]<low[v]) a[++cnt]={min(u,v),max(u,v)};
}else low[u]=min(low[u],dfn[v]);
}
}
//点双
void tarjan(int u){
dfn[u]=low[u]=++t;st[++top]=u;int f=0;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);++f;
if(dfn[u]<=low[v]){
a[++ans].push_back(u);
while(st[top+1]!=v) a[ans].push_back(st[top--]);
}
}else low[u]=min(low[u],dfn[v]);
}if(u==rt&&!f) a[++ans].push_back(u);
}
//边双
void tarjan(int u,int fa){
dfn[u]=low[u]=++t;s[++top]=u;
for(in ti=0;i<g[u].size();++i){
int v=g[u][i];
if(!dfn[v]){
tarjan(v,u);
if(low[v]>=dfn[u]) continue;
low[u]=min(low[u],low[v]);
}else if(v^fa) low[u]=min(low[u],low[v]);
}if(dfn[u]==low[u]){
vis[u]=0;fa[u]=++sum;
while(s[top]^u){
vis[s[top]]=0;f[s[top--]]=sum;
}--top;
}
}