首页 > 其他分享 >有向图的连通性

有向图的连通性

时间:2024-03-07 21:55:07浏览次数:22  
标签:连通 有向图 连通性 SCC num DFS low 遍历

强连通:如果两个点彼此都能到达对方,那么这两个点是连通的。如果一个图中任意两个点都连通,那么这个图是强连通图。

强连通分量:如果一个图不是强连通图,那么可以将其分为多个子图,使得每个子图强连通且不能与其他的子图形成强连通,那么每个子图就是强连通分量。简单点说,如果将所有子图缩成一个点,缩完后图中没有环,那么每个子图就是强连通。可以缩写为 SCC。

SCC 实际上就是一个环,然后再扩展一些点所得到的图。因此求 SCC 实质上就是找环并尽可能地扩大环。

下面介绍比较常用的 Tarjan 算法:

1 Tarjan 算法

先对图进行 DFS,形成一棵 DFS 树。DFS 树就是从根节点开始搜索,如果到达了一个没有访问过的点,那么将这条边加入树中,并标记访问。

举个例子:

该图的 DFS 树为:

我们称 DFS 树上的边为树边,通往自己祖先的边为回边,其它的边为横叉边。如上图中,\(2 \to 3\) 是树边,\(4 \to 2\) 是回边,\(5 \to 4\) 是横叉边。

回边能构成环吗?答案是肯定的。因为我可以从这个点走向祖先,然后再从祖先走向这个点。

横叉边能构成环吗?一条横叉边显然不能构成。那么有人会说了,两条呢?

我们把上面的图改一下:

这样树边 \(6 \to 7\),横叉边 \(7 \to 5\) 与 \(5 \to 6\) 是不是就构成环了?

实际上这样是不合法的。注意这是一个 DFS 树,那么我们在搜索到 \(5\) 的时候,会遍历到 \(6\),而不会再从 \(1\) 过去了。

那么到底能不能构成呢?答案是不能,但它有可能扩大回边所构成的环。原图中,横叉边 \(5 \to 4\) 扩大了回边 \(4 \to 2\) 所构成的环。

那么如何找环呢?

我们为每个点设置两个参数:一个是 \(num\)(大部分人喜欢称为 \(dfn\)),一个是 \(low\)。\(num_u\) 表示 \(u\) 的 DFS 序,\(low_u\) 表示从 \(u\) 出发能到达的自己的祖先中 DFS 序最小的点的 \(num\) 值。

如上图中,\(num=\{1,2,3,4,5,6\},low=\{1,2,2,2,2,6\}\)。

\(low_6=6\) 而不是 \(2\),因为 \(2\) 不是 \(6\) 的祖先。

这时我们可以发现:所有 \(low\) 值相等的点在同一个 SCC 中,这些 SCC 中一定有一个点的 \(num\) 值等于 \(low\) 值,我们可以把这个点设为 SCC 的根。

我们可以用一个栈,每次搜到结点就将该结点入栈。在遍历完所有出边后,如果该点的 \(num\) 值等于 \(low\) 值,那么栈顶的点就都属于该 SCC,全部弹出并标记即可。

因此,只要我们算对 \(low\) 值,就能求出 SCC。

那么怎么算呢?

初始时,每个点的 \(num\) 值和 \(low\) 值相等,因为我可以从自己出发走到自己。

在遍历图时,对于边 \(u \to v\):

  • 该边是树边

那么我们应该将 \(low_u\) 与 \(low_v\) 取最小值,因为我从 \(v\) 出发能到达的祖先,我从 \(u\) 出发先到 \(v\) 的话也能到达这些祖先。

  • 该边不是树边

我们也应该更新 \(low_u\)。那么应该用 \(num_v\) 更新还是 \(low_v\) 更新呢?

答案是都可以。如下图:

下图中的 DFS 树中的边为 \(1 \to 2,2 \to 3,3 \to 4\)。

我们在遍历到 \(3\) 的时候,假设我们先走的 \(3 \to 4\) 这条边,然后我们走到了 \(4\)。该点只有一个出点 \(2\),而 \(2\) 还没搜完,它的 \(num\) 值和 \(low\) 值都为 \(2\),但是我们可以从 \(2\) 走到 \(3\) 再走到 \(1\),且 \(1\) 是 \(4\) 的祖先。因此不管用 \(num_u\) 还是 \(low_u\) 更新都不能算对 \(low\) 值。能正确找出所有 SCC 的前提是 \(low\) 值都算对。

但实际上我们用了一个栈,在找到根节点的时候会把所有栈顶的点都弹出。因此我们只需要保证该点的 \(num\) 值不等于 \(low\) 值而不会被判断成 SCC 的根即可。因为 \(v\) 已经遍历过了,因此 \(v\) 的 \(num\) 值一定小于 \(u\) 的 \(num\) 值,因此两种都可以。我们一般使用 \(num\) 值来更新。

这就是 Tarjan 算法的流程。下面给出例题和代码。

例题 洛谷-B3609

我们可以像链式前向星一样,把每个点所属的 SCC 编号向该点的编号加边,这样遍历每个 SCC 编号的出边就能遍历到该 SCC 的所有点了。当然,也可以使用 vector 保存每个 SCC 中的点。

代码

强连通分量的一个应用是缩点。

例题 洛谷-P3387

该题的思路为:如果我到达了一个环,那么我可以在环上逛一圈,把环上的所有点的权值都加上,然后再走到环上的任意一点离开环。于是我们可以把环缩成一个点,这个点的权值就是环上所有点的权值的和。在代码中,我们可以再建个图,加边时将原来图中所有的 \(u \to v\) 改为 \(scc_u \to scc_v\) 加边。这样新图就是一个有向无环图,我们可以使用拓扑排序 \(+\) DP。

代码

标签:连通,有向图,连通性,SCC,num,DFS,low,遍历
From: https://www.cnblogs.com/lrxmg139/p/18059864

相关文章

  • 测试网络端口连通性
    简介:在网络服务中,经常需要测试是否能连接服务器,ping服务器地址能通只能表示三层网络没问题,而不能表示上层服务端口号正常,而这就需要我们运用工具来测试四层端口号是否正常?可以通过Telnet、nc、ssh命令来测试端口连通性1、TelnetTelnet只能用于测试TCP端口,而nc即可用于测试TCP......
  • 【学习笔记】《综述图论中连通性及相关问题的一些处理方法》
    2023集训队论文第一篇。发现好像存在很多我不会/见过但是从来没记住过的结论之类的,所以这篇主要是背结论用的。目录无向图双连通性点双连通分量的性质耳分解割空间与环空间有向图可达性问题强连通性有向环竞赛图记\(u\rightsquigarrowv\)为\(u\)到\(v\)的路径,\(u\t......
  • Windows如何检测UDP端口的连通性
    在Windows平台上如何检测UDP端口的连通性呢?其实,平时我们遇到检测TCP端口的连通性的情况比较多,遇到检测UDP端口连通性的情况较少。而且检测UDP端口的连通性比较复杂一点。像检测TCP端口是否连通(放开),Windows平台,一般常用的工具有telnet、psping等工具,而检测UDP端口的工具,在Linux平台......
  • 动态图连通性
    Describe:你要维护一张无向简单图(即没有自环,没有重边的无向图)。你被要求加入删除一条边及查询两个点是否连通。0:加入一条边。保证它不存在。1:删除一条边。保证它存在。2:查询两个点是否联通。允许离线Solution:对于离线做法,可以用线段树分治加可撤销并查集,时间仅\(O(n\lo......
  • 相对次序建有向图——cf_925_F. Chat Screenshots
    目录问题概述思路分析参考代码做题反思问题概述原题参考:F.ChatScreenshots聊天室内有n个人,存在一定的顺序,但是每个人看顺序时都会把自己放到最前面,其余人的位置不变,现在给出k组长度为n的排列,问是否冲突思路分析对于k组排列,除了自己的位置未知外,其余人的相对次序都是正确的......
  • 图的连通性
    图的连通性这个专题,不太好说,因为涉及到的东西实在是太广泛太杂了,我们这里就只讲建模,至于建模之后的处理方式可以移步至其他的知识点。强连通对于有向图,我们可以发现,如果每个点的贡献和影响与这个点可达的点有关,那么我们就可以将一个强连通分量缩点,将原图转化为一个有向无环图,然......
  • 图论——连通性
    图论——连通性基本知识路径相关途径:连接一串结点的序列称为途径,用点序列\(v_{0..k}\)和边序列\(e_{1..k}\)描述,其中\(e_i=(v_{i-1},v_i)\),通常写为\(v_0\tov_1\to\cdots\tov_k\)。迹:不经过重复边的途径称为迹。回路:\(v_0=v_k\)的迹称为回路。......
  • 连通性问题
    求割点#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllN=2e4+10;lln,m,dfn[N],low[N],tot,root;boolcut[N];vector<ll>G[N];voidtarjan(llu){ dfn[u]=low[u]=++tot; llflag=0; for(autov:G[u]){ if(!dfn[v]){ ta......
  • 网络连通性测试 【Connectivity】
    CFD简介CFD(ConnectivityFaultDetection,连通错误检测)是一种二层网络中的端到端OAM(Operation,Administration,andMaintenance,操作、管理和维护)技术,主要用于在二层网络中检测链路连通性,以及在故障发生时进行定位。适用的二层网络包括基于VLAN的以太网网络和基于MPLS的二层V**。......
  • 连通性容斥
    一种比较牛的东西,典型标志为\(n\le18\),计数满足特殊性质而且连通的状物。[ARC105F]有一张\(n\)个点\(m\)条边的简单无向图,问选出一个边集,使得\(n\)个点与这些边构成的图连通,并且图是二分图的方案数。\(1\leqn\leq17,n-1\leqm\leq\frac{n(n-1)}{2}\)。通用套路......