tarjan进阶
Posted yzxverygood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tarjan进阶相关的知识,希望对你有一定的参考价值。
一、边双连通分量
定义
若一个无向图中的去掉任意一条边都不会改变此图的连通性,即不存在桥,则称作边双连通图。一个无向图中的每一个极大边双连通子图称作此无向图的边双连通分量。
实际求法和强连通分量差不多,只是要注意由于一条无向边被分为两条有向边存储,所以在经过其中一条从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进阶的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段