【算法及其原理】 Tarjan——求有向图中的强连通分量

算法竞赛——强连通分量 强连通分量 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通。 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图也可以说,在强连图图的基础上加入一些点和路径,使得当前的图不在强连通,称原来的强连通的部分为强连通分量。 DFS生成树 DFS生成树是根据DFS搜索顺序构成的一颗生成树,形如(自上而下,自左而右): 有向图的 DFS 生成树主要有 4 种边: 树边(tree edge):示意图中以黑色边表示,每次搜索找到一个还没有访问过 阅读详情

强连通分量定义:

在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。


Tarjan算法:

假设图有n个节点,m条边。该算法可以在O(n+m)的时间复杂度中输出所有强连通分量

所用数据结构说明:

数组 dfn[]:记录每个点按照DFS被访问顺序的时间戳

数组 low[]:记录每个点所能访问到的时间戳最靠前的点的时间戳

栈 S:按顺序记录当前DFS树中的节点

算法流程:

tarjan(u){

    dfn[u] = low[u] = ++index

    S.push(u)

    for each (u, v) in E

        if (v is not visited)

            tarjan(v)

            low[u] = min(low[u],low[v])

        else if (v in S)

            low[u] = min(low[u],dfn[v])

        if (dfn[u] == low[u]) {

            w = S.pop()

        } until (w == u) //将该点之前的所有点作为一个强连通分量出栈

}


算法原理:

1、为什么出栈的部分是强连通分量:

①设结束点为k,则对于任意非结束点i,有low[k] = dfn[k] <= low[i] < dfn[i]

②每一次出栈的节点必然是深搜树中某一棵子树的全部节点

结合以上两点,我们可以发现:这一部分的任何一个点都可以访问到结束点,结束点可以访问到任何一个点,所以任意两点间必然能够有回路,得证

对于前者,利用反证法:假设这一部分点中存在一个点无法回访到结束点,则设其能够回访到的dfn最小的点为i,则由性质①可得low[i] < dfn[i],即i可以访问到dfn更小的点,故矛盾

对于后者,由性质②结合性质①后半部分可得,结束点必为该子树的根,由DFS性质可得,其必能访问到之后的每一个点

※关于第②点,有两种考虑方法:

i)整个深搜和访问(判断low[i]与dfn[i])实际上是后序遍历,所以每一个被确定的结束点必然是一棵子树的根 

ii) 反证法:如果这些点分处在多棵子树中,那么在回溯时,靠前的部分会被先从搜索树中除去(从栈中弹出)


2、为什么出栈的部分是完整的强连通分量:

假设出栈的是不完整的强连通分量,则其剩余的部分结点可能存在三种情况:

①在栈中

②尚未进栈

③之前已经出栈

对于情况②:尚未进栈意味着不存在一条由已知点通向该点的路,所以必然不可能处于该强连通分量中

对于情况①:假设此时的结束点为i,则对于栈中的任意点j,此次出栈的任意点k,有dfn[j] < dfn[i] <= low[k],即此次出栈的任意点都无法回访到尚在栈中的点,故不可能处于该强连通分量中

对于情况③:与情况①相同(此次出栈的部分等价于对之前某次出栈操作而言的“在栈中”部分)

参考链接:http://blog.youkuaiyun.com/zakheav/article/details/46424251

参考了这位老哥的证明逻辑以及对于第二个问题的证明,但是对于第一个问题,即“为什么是强连通的”,我对于他的证明存有疑问:边BA不存在于回路中为什么能够得到low[A] == dfn[A]?

A虽然不能回访到B,但可以指向他所绘图中B所在的红圈圈中的其他点,因为我们此时的条件是存在一条边不在回路中,而不是仅存在一条边不在回路中,所以B所在的红圈中可能存在点和B在不同的搜索子树上且不指向B


Open3D KD-tree的使用【2025最新版】 Open3d使用FLANN构建KDTree以便进行快速最近邻检索。博客长期更新,本文最近一次更新时间为:2025年1月1日,代码已同步更新至Open3D 0.18.0版本。 阅读详情

相关推荐

麒麟桌面操作系统QT开发环境搭建

麒麟操作系统安装Qt

因为热爱,所以坚持,记录工作中的乐趣 9273

浅谈Tarjan求强连通分量

首先,要知道什么是强连通分量,这个还是比较简单的吧。 那么就谈谈Tarjan求强连通分量。 概率(扯淡) 首先,Tarjan算法是基于对图深度优先搜索(DFS)的算法,每个强连通分量为搜索树中的一个子树。 搜索时把当前搜索树中未处理的结点加入一个栈,回溯时可以判断栈顶中的结点是否构成一个强连通分量。 DFS的过程中遇到的四种边: 1、树枝边:DFS时经过的边,即DFS搜...

lahlah的博客 1121

Linux 之 supervisor安装和使用

运行Supervisor的后台服务,它用来启动和管理那些你需要Supervisor管理的子进程,响应客户端发来的请求,重启意外退出的子进程,将子进程的stdout和stderr写入日志,响应事件等。它是Supervisor最核心的部分。

chang995196962的博客 5545

强连通分量

强连通分量@(算法学习)首先明白,这个概念是在有向图中的,其次是,如何有效寻找。图中强连通分量的个数是:4个。分析: 强连通分量的定义:有向图中,如果两个顶点vi,vjv_i,v_j之间存在: viv_i到vjv_j的路径 vjv_j到viv_i的路径 则称这两个顶点是强连通的。至于相对的弱连通,则抹去方向,相连即可。那么,道理很简单,如何应用呢?答案是先找回路,然后在回路的基础上,扩展结点。因为

Bing's Blog 2868

Proteus快速入门(最详细教程)

Proteus 是一款用于嵌入式单片机仿真的软件,用于在打PCB板之前对软件程序和硬件电路的正确性进行仿真验证。1.所以Proteus一般会和Keil软件进行联合仿真,在Proteus中绘制系统的电路图,在Keil软件中编写对应的程序后生成Hex文件。2.Proteus的仿真结果仅供参考,只能在一定程度上验证系统的可能性。实际实物系统还需要进行进一步的调试。以上即为本次分享的Proteus入门教程的全部内容,希望可以能够帮助到各位道友。

ediykk的博客 15万+

fanuc机器人I/O分配

FANUC机器人在和其他外部设备进行通讯时,需要对信号进行配置。 在机器人处于UOP自动分配状态时,系统会自动检索已配对设备,并分配相应的机架号。 当我们需要手动对信号进行分配时,可参考以下机架号进行配置。 不同的通讯协议对应的机架号不同,外部通讯协议常用的机架号参考下表: 序号 机架号 通讯类型 1 0 Process I/O 2 1-15

haier123888的博客 1万+

图论学习-有向图强连通分量

文章目录有向图强连通分量1.定义:2.基本术语与概念2.1 边的概念2.2 缩点2.3 时间戳3. tarjan求强连通分量(SCC)3.1 原理3.2 步骤3.3 模板3.3.1 tarjan求强连通分量的过程3.3.2 缩点的过程4.例题题目1:P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G题目2:5.参考资料 有向图强连通分量 1.定义: 给定一张有向图,若对于图中任意两个节点x,y,既存在从x到y的路径,也存在y到x的路径,则该有向图是强连通图。 有向图的极大强连通子图被称

麒麟001号的博客 2463

解决:请求的资源[/xxx/]不可用 描述 源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。

解决:请求的资源[/xxx/]不可用 描述 源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。

念兮为美 1万+

有向图的强连通分量(tarjan算法)

考虑强连通分量C,设其中第一个被发现的点为x,则,C中其他的点都是x的后代。我们希望在x访问完成时立即输出C(可以同时记录C,输出代表当前在当前的遍历序列中剔除),这样就可以在同一颗DFS树种区分开所有SCC了,因此问题的关键是判断一个点是否为一个SCC中最先被发现的点。

Winjourn的专栏 4025

ABAP 系统里使用 SAP Joule 辅助编程的前提条件

只是说这些大语言模型是针对互联网上能够挖掘到的所有数据进行训练,不像 SAP Joule 那样术业有专攻,仅仅深耕 SAP 技术和业务领域,因此大伙儿对 SAP Joule 的期望值,也远远高于通过大语言模型。SAP Joule 从 ABAP Development Tool 的 Chat 窗口中接收到的对话请求,都会路由到 SAP BTP 上的 AI Foundation.在上述 ABAP 环境中启用 SAP Joule,需要购买额外的 license:8019124.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 796

Android PMS——概述(一)

PMS(Package Manager Service)是 Android 操作系统的一个重要组件,它负责管理应用程序的包信息以及与应用程序的安装、卸载、权限控制等相关功能,确保应用程序的安全性和稳定性。 Android PMS 负责维护一个应用程序包的清单信息,该清单是一个 XML 文件,包含应用程序的各种元数据,例如应用程序的包名、版本号、权限要求、组件信息等。PMS通过访问该清单文件来获取应用程序的信息。 此外,Android PMS 还负责应用程序的安装和卸载。在安装应用

小旭的专栏 1667

Tarjan算法 求有向图的强连通分量 C++实现

求有向图的强连通分量 Tarjan算法 参考思路解析:trajan算法 示例: 输入样例: 8 9 // 节点个数,连接个数 1 3 // 每条边的起始点和结束点 2 1 3 2 3 4 4 5 5 6 6 7 7 8 8 5 输出样例: low: 1 1 1 4 5 5 5 5 dfn: 1 3 2 4 5 6 7 8 scc: 3 3 3 2 1 1 1 1 // 每个元素对应的强连通分量的标号 subnum: 4 1 3 // 不同子集包含的元素个数 C++ 代码实现: #includ

weixin_43155243的博客 844

大模型长对话中上下文无法承载全部历史,如何压缩或提取重点

如果说截断和滑动窗口是“硬性”压缩,那摘要生成技术就显得“软”多了,也更接近于智能化的解决方案。它的思路是:不直接丢弃历史,而是通过自然语言处理(NLP)技术,把冗长的对话记录浓缩成一段简短的摘要,保留核心信息。这样既能大幅减少token数量,又不至于丢失关键内容。这种方法通常会借助预训练模型,比如BART或T5,它们擅长从长文本中提取重点内容。

大模型大数据攻城狮的专栏 1587

关于图论中Tarjan算法的一些总结

Tarjan算法求强连通分量 前置知识 1.1.1.有向图:一个只由有向边构成的图,Tarjan算法只适用于有向图。 2.2.2.强连通: 对于两个点A,BA,BA,B,如果他们之间可以相互到达,那么就称点A,BA,BA,B强联通。 对于一个图GGG,如果其任意两个顶点都是强联通的,那么这个图就是一个强联通图。 对于一个非强联通图GGG,如果其某一子图G′G'G′为强联通图,那么G′G'G′就被称...

wljoi的博客 763

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【算法模板】图论:Tarjan算法求强连通分量

Tarjan 算法是一种高效的求有向图中所有强连通分量的方法。一个强连通分量(SCC)是一个极大子图,其中任意两个顶点之间都是可达的。

2303_80346267的博客 1322

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

关于有向图的强连通分量

有向图的强连通分量 一个有向图中,如果节点i能够通过一些边到达节点j,就简写成i能到达j。如果对于任意两个节点i,j均有i能到达j或j能到达i,则说此图是连通的。如果对于任意两个节点i,j均有i能到达j且j能到达i,则说此图是强连通的。 对于一个无向图,说强联通没有意义,因为此时强连通就是连通。而对于一个有向图,它不一定是强连通的,但可以分为几个极大的强连通子图(“极大”的意思是再加入任何一个顶点

wuxinliulei的专栏 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Tarjan系列

Tarjan算法作为一类算法,不同的应用写法不同,需要注意。 Tarjan求割点/桥: low[u]表示点u及其后代通过返祖边可以访问到的最小时间戳,所以不能回到父节点去。 割点有两种情况: (1)该点不是根节点,且该点的孩子结点不通过该点回不到祖先节点 (2)根节点显然不能通过上一条判断,所以需要对根节点进行特判,对于根节点,只要他有两个及以上的孩子结点,他就是一个割点 int n,m; set...

欢迎光临 我的心 165

Tarjan算法求割点、割边、SCC(缩点)

文章目录Tarjan算法的应用无向图中求割点(割顶)求割边(桥)有向图中求SCC且缩点 Tarjan算法的应用 本文不介绍算法实现(毕竟其他算法实现太多讲的了),只提供自己整理的模板(我认为我这版代码看应该最舒服了) 一些概念: 割点 割边 SCC DCC Tarjan算法: 时间戳 dfn[i]dfn[i]dfn[i] 搜索树 回溯值 low[i]low[i]low[i] 无向图中 求割点(割顶) 割边判定法则:xxx 是割点   ⟺  \iff⟺ 存在 xxx 的搜索树上的一个子节

xxayt的博客 928

新手强连通学习

一、定义 在有向图G中,如果两个顶点u,v间有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向非强连通图的极大强连通子图,称为强连通分量。 图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达。{5},{6}也分别是两个强连通分量。 二、tarjan算法 时间复杂度是O(N+M) 四条边...

Starry_Sky_Dream的博客 318

【wikioi】2822 爱在心中

题目链接 算法:Tarjan+dfs(最短路的都行,判连通而已) 先了解一下什么是Tarjan Tarjan算法用于求出图中所有的强连通分量。 转自NOCOW:点击打开链接 ============================================================================ 在有向图G中,如果两个顶点间至少存在一条路径,称两...

112

【C++】Tarjan算法

相关介绍 强连通分量 在有向图中,如果某一个子图的任意两点都是连通的则该子图是一个强连通分量。 算法简介 TarjanTarjanTarjan算法有好几种,都是以TarjanTarjanTarjan命名的,这里讲的TarjanTarjanTarjan指求强连通分量的TarjanTarjanTarjan算法,他以深度优先搜索的方式对图进行染色,进而求得强连通分量。 算法思想 在一个顶点数为nnn的图中,TarjanTarjanTarjan算法需要维护一个顶点栈和几个数组。 stack Sstack

cout0 1101

luogu P3387 【模板】缩点

说实话,我作为初学者,学起来挺吃力。可能是鄙人智力有限的原因。

soilovedogs的博客 704

沉迷TARJAN无法自拔系列

最近一口气看见了6道TARJAN,没有一道在比赛的时候打对,感觉自己菜哭了。 tarjan这么基础的算法都没能完全掌握,,然后恶补了几天,感觉以后遇见tarjan题应该不会打不出来了(flag高高立起) 这篇博文会全面介绍tarjan的所有用途(选手自己挖掘的不算,我又不知道。): 1.求有向图的强连通分量 2.求无向图的割顶和桥 3.求无向图的双连通分量 4.判断是否为二分图(其实是d

老臣 403

连通性1(Tarjan 理论版)

一、无向图割点、桥、双连通分量Tarjan 算法求割点和桥(割边)求“割点”的代码 边双和点双连通分量边双连通分量 和 点双连通分量 的缩点 二、有向图强连通分量1.有向图的弱连通与强连通2.强连通分量Kosaraju算法Tarjan 算法(求强连通分量)

**祺的博客 960

有向图强连通分量

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达。{5},{6}也分别是...

weixin_30642305的博客 91

有向/无向图Tarjan

调题调得脑雾了,不必在意一些奇怪的变量名和注释。图的特点是有环,这些环使得我们无法使用 DP 等需要在 DAG 或树上进行的算法。tarjan 通过在搜索过程中构建 dfs 搜索树,将图上的边分成树边和非树边,解决一类问题。在一个有向图中,若任意两点都可以互相到达,这个有向图称为强连通图。 一个有向图的一个是强连通图的子图称为一个强连通子图。 一个极大的强连通子图就是强连通分量。 注意:这里是极大而不是最大,极大的意思是不存在一个比它大并且完全包含它的强连通子图。我们规定一个点 rtrtrt 为根。从根 r

STY_fish_2012的博客 210
上一篇: USACO 6.5.5 Checker Challenge 回溯
下一篇: 【辨析】CLI和Shell的区别
Frontier_Setter
博客等级 码龄10年 2粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值