算法学习笔记:连通图详解

本文详细介绍了图论中的连通图概念,包括无向图和有向图的连通性。接着,重点探讨了强连通分量(SCC)的定义和算法,特别是Tarjan算法。通过对DFS生成树的分析,解释了如何利用DFS判断强连通分量,并提供了伪代码和实现。此外,文章还提到了Kosaraju算法和Garbow算法作为求解强连通分量的替代方案。最后,讨论了割点、桥的概念以及它们的求解方法,为理解图的结构和性质提供了深入的见解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是连通图 ?
在图论中,连通图基于连通的概念。在一个无向图 G 中,若从顶点 i 到顶点 j 有路径相连(当然从 j 到 i 也一定有路径),则称 i 和 j 是连通的。如果 G 是有向图,那么连接 i 和j的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径)。

简单的来讲就是,

强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通。

强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图。

这里将会介绍的是如何来求强连通分量的算法、割点和桥 以及双连通分量。

Tarjan 算法发明人
Robert E. Tarjan(1948~) 美国人。

你是不是感觉Robert E. Tarjan 这个名字很熟悉?

没错,Robert E. Tarjan和John E. Hopcroft就是发明了深度优先搜索的两个人——1986年的图灵奖得主。

除此之外 Tarjan 发明了很多算法结构。光 Tarjan 算法就有很多,比如求各种连通分量的 Tarjan 算法,求 LCA(Lowest Common Ancestor,最近公共祖先)的 Tarjan 算法。并查集、Splay、Toptree 也是 Tarjan 发明的。

你看牛人们从来都不闲着的。他们到处交流,寻找合作伙伴,一起改变世界。

我们这里要介绍的是他的在有向图中求强连通分量的 Tarjan 算法。

另外,Tarjan 的名字 j 不发音,中文译为塔扬。

DFS 生成树
在介绍该算法之前,先来了解 DFS 生成树 ,我们以下面的有向图为例:

scc1.png

有向图的 DFS 生成树主要有 4 种边(不一定全部出现):

树边(tree edge):绿色边,每次搜索找到一个还没有访问过的结点的时候就形成了一条树边。
反祖边(back edge):黄色边,也被叫做回边,即指向祖先结点的边。
横叉边(cross edge):红色边,它主要是在搜索的时候遇到了一个已经访问过的结点,但是这个结点 并不是 当前结点的祖先时形成的。
前向边(forward edge):蓝色边,它是在搜索的时候遇到子树中的结点的时候形成的。
我们考虑 DFS 生成树与强连通分量之间的关系。

如果结点 u 是某个强连通分量在搜索树中遇到的第一个结点,那么这个强连通分量的其余结点肯定是在搜索树中以 u 为根的子树中。 u 被称为这个强连通分量的根。

反证法:假设有个结点 v 在该强连通分量中但是不在以 u 为根的子树中,那么 u 到 v 的路径中肯定有一条离开子树的边。但是这样的边只可能是横叉边或者反祖边,然而这两条边都要求指向的结点已经被访问过了,这就和 u 是第一个访问的结点矛盾了。得证。

Tarjan 算法求强连通分量
在 Tarjan 算法中为每个结点 u 维护了以下几个变量:

dfn[u] :深度优先搜索遍历时结点 u 被搜索的次序。

low[u] :设以 u 为根的子树为 Subtree(u) 。 low[u] 定义为以下结点的 dfn 的最小值: Subtree(u) 中的结点;从 Subtree(u) 通过一条不在搜索树上的边能到达的结点。

ps:每次找到一个新点,这个点low []=dfn []。

一个结点的子树内结点的 dfn 都大于该结点的 dfn。

从根开始的一条路径上的 dfn 严格递增,low 严格非降。

按照深度优先搜索算法搜索的次序对图中所有的结点进行搜索。在搜索过程中,对于结点 u 和与其相邻的结点 v (v 不是 u 的父节点)考虑 3 种情况:

v 未被访问:继续对 v 进行深度搜索。在回溯过程中,用 low[v] 更新 low[u] 。因为存在从 u 到 v 的直接路径,所以 v 能够回溯到的已经在栈中的结点, u 也一定能够回溯到。
v 被访问过,已经在栈中:即已经被访问过,根据 low 值的定义(能够回溯到的最早的已经在栈中的结点),则用 dfn[v] 更新 low[u] 。
v 被访问过,已不在在栈中:说明 v 已搜索完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值