弱连通和强连通_基本图论-连通分量(强/弱联通 割点/边 边/点双)

本文深入探讨图论中的核心概念,包括强连通分量、弱连通分量、割点、割边以及边双连通分量和点双连通分量。通过定义、性质和算法解释,帮助初学者理解这些概念的差异和相互关系,并提供了相应的代码示例进行辅助说明。
摘要由CSDN通过智能技术生成

前言

网上现存\(60\%\)的文章都有明显的误区,本文章经过多次修改,能保证正确性

本文涉及强连通分量、弱连通分量、割点、割边、边双、点双,属于基本图论范畴

在有着直接关联的基础上又有所不同,本文基于把抽象的数组转换为在图上的意义,旨在让初学者能更轻松地理解并区分差别

为避免各个板子的差别过大,在正确的基础上尽量保证代码的相似性

如果您之前学过,可能与您的定义有所不同,故请在看完每个算法下面的代码后再进行文字阅读

文字中某个词语后出现带圆框的数字,如①②,这些词语将会在文字下方有详细的注释,方便阅读

前置

我们简略地定义\(dfs\)树为遍历路程中路径所组成的一棵树,注意下面说的儿子、叶子节点、子树边界\((\)与子树直接相连的外部节点\()\)等用法都从此基础上得出

如下图及\(dfs\)树,\(3,7\)为\(1\)的儿子,叶子节点为\(2,5,6,8\),\(7\)的子树边界为\(\{1\}(1\)与\(7\)和\(8\)直接相连\()\),如果新加一条边\((3,4)\),则\(7\)的子树边界为\(\{1,3\}\)

有向图

强连通分量

定义:有向图中某个点集中的点互相能到达的分量为强连通分量

为方便理解我们采取归纳法:找到完整强连通分量后立即染色

定义\(dfn_u\):表示\(dfs\)中\(u\)的时间戳;初始化为第几个被遍历到的点。

定义\(low_u\):表示\(u\)能到达且在\(u\)子树边界的未染色的最小时间戳①\((\)设代表该最小时间戳点的点为\(x\),可证明\(x\)一定能与\(u\)组成强连通分量②\()\);初始化为\(dfn_u\)。

①:显然代表该最小时间戳的不为\(u\)的子树\((\)除\(u)\),因为子树内的时间戳\(u\)已经为最小的了。故\(u\)的子树并不影响\(low_u\),真正影响的是\(u\)的子树外,与\(u\)子树有接触,且未染色的。

②:\((\)下图为例\()x\)位于\(f\)的左子树,\(x\)所在完整强连通内所有节点不止在左子树\((\)否则就染色了\()\),\(x\)至少能与\(f\)组成强连通分量。故\(x\)一定能与\(u\)组成强连通分量:\(f\rightarrow u\rightarrow x\rightarrow f\)。

具体做法:在\(u\)的子树遍历完后,\(low_u=dfn_u\)则把栈顶到该点的区间染色\((\)与子树外单向联通,那\(u\)的子树未处理部分与\(u\)组成强连通分量\()\),否则要等回到某个祖先后染色才能分量的完整

code

也可更换第\(7\)行代码为:

else if(visit[v]) low[u]=std::min(low[u],low[v]);

//此时定义low:能与u组成强连通分量(未染色)的最小时间戳

void Tarjan(LL u){

dfn[u]=low[u]=++tim; sta[++top]=u; visit[u]=true;

for(LL i=head[u];i;i

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值