标签:tarjan style 割点 continue 无向图 turn strong code 返回
一、边双连通分量
定义
若一个无向图中的去掉任意一条边都不会改变此图的连通性,即不存在桥,则称作边双连通图。一个无向图中的每一个极大边双连通子图称作此无向图的边双连通分量。
实际求法和强连通分量差不多,只是要注意由于一条无向边被分为两条有向边存储,所以在经过其中一条从u到达v之后不能再通过另一条边由v返回u。
代码
inline void tarjan(int x,int fa){
dfn[x]=low[x]=++cnt;
a.push(x);
ist[x]=1;
int wh=0;
for(int i=0;i<v[x].size();i++){
if(v[x][i]==fa&&!wh){
wh=1;
continue;
}
if(!dfn[v[x][i]]){
tarjan(v[x][i],x);
low[x]=min(low[x],low[v[x][i]]);
}else if(ist[v[x][i]]){
low[x]=min(low[x],dfn[v[x][i]]);
}
}
if(dfn[x]==low[x]){
sum++;
while(1){
int u=a.top();
a.pop();
ist[u]=0;
belong[u]=sum;
if(u==x)break;
}
}
return;
}
二、割点
定义
在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多,就称这个点集为割点集合。
也就是说对于一条边的两个节点u和v,如果low[v]>=dfn[u]则u是一个割点(dfn[u]<dfn[v])。
代码
inline void tarjan(long long x,long long fa){
dfn[x]=low[x]=++cnt;
long long son=0;
for(long long i=0;i<v[x].size();i++)
if(v[x][i]!=fa){
if(!dfn[v[x][i]]){
son++;
tarjan(v[x][i],x);
low[x]=min(low[x],low[v[x][i]]);
if(low[v[x][i]]>=dfn[x])is[x]=1;
}else low[x]=min(low[x],dfn[v[x][i]]);
}
if(!fa&&son==1)is[x]=0;
return;
}
标签:tarjan style 割点 continue 无向图 turn strong code 返回
原文地址:https://www.cnblogs.com/yzxverygood/p/9525924.html