Kosaraju算法解析及Java代码实现(附图)

【图论】Kosaraju算法详解 讲 Kosaraju 算法之前要先知道什么是强连通分量(SCC) 强连通分量 对于一个有向图顶点的子集 S ,如果在 S 内取两个顶点 u 和 v ,都能找到一条从 u 到 v 的路径,那么就称 S 是强连通的。 如果在强连通的顶点集合 S 中加入其他任意顶点集合后,它都不再是强连通的,那么就称 S 是原图的一个强连通分量(SCC:strongly connected componen... 阅读详情

强连通分量

强连通分量只可能存在于有向图中,无向图中是不存在强连通分量的。下图很形象地指出了图中所包含的强连通分量。

上图中存在5个强连通分量(阴影部分)。

 

拓扑排序

定义:给定一副有向图,将所有的顶点排序,使得所有的有向边均从排在前面的元素指向排在后面的元素。

如下图所示,左边是一个有向无环图,箭头方向代表了其执行方向,也就是边的方向。右边是通过计算得到的拓扑排序,其实从图中可以看出,拓扑排序最重要的就是为我们的有向图理顺了其内在的先后顺序,应用中一般使用拓扑排序来解决调度问题。

划重点:一幅有向无环图的拓扑顺序即为所有顶点的逆后序排列。

 

Kosaraju算法

算法流程:

(1)对原图G取反GT(也称转置图)

(2)从任意一个顶点开始对反向图GT进行逆后续DFS遍历,获得图的拓扑排序reversePost

(3)按照逆后续遍历reversePost中 节点的出栈顺序,对原图G 进行DFS遍历,一次DFS遍历中访问的所有顶点都属于同一强连通分量。

 

算法思路:

图G 中有两个强连通分量,即强连通分量A 和强连通分量B,分别由顶点 A0-A1-A2 和顶点 B3-B4-B5 构成。每个连通分量中有若干个可以相互访问的顶点(这里都是3个),强连通分量与强连通分量之间不会形成环,否则应该将这些连通分量看成一个整体,即看成同一个强连通分量。

我们假设,DFS从强连通分量B 的任意一个顶点开始,那么恰好遍历整个图需要2次DFS,而且每次DFS遍历的顶点恰好属于同一个连通分量。我们若从连通分量A 中任意一个顶点开始DFS,此时我们只需要一次DFS就访问了所有的顶点。所以,我们不应该按照顶点编号的自然顺序或者任意其它顺序进行DFS,而是应该按照被指向的强连通分量的顶点排在前面的顺序进行DFS。上图中由强连通分量A指向了强连通分量B。所以,我们按照

B3, B4, B5, A0, A1, A2

的顺序进行DFS,这样就可以达到我们的目的。但事实上这样的顺序太过严格,我们只需要保证被指向的强连通分量的至少一个顶点排在指向这个连通分量的所有顶点前面即可,比如

B3, A0, A1, A2, B4, B5

B3排在了强连通分量A所有顶点的前面。

这就是Kosaraju的算法思想:对原图取反,然后从反向图的任意节点开始进行DFS的逆后序遍历,逆后序得到的顺序一定满足我们的要求。

DFS的逆后序遍历是指:如果当前顶点未访问,先遍历完与当前顶点相连的且未被访问的所有其它顶点,然后将当前顶点加入栈中,最后栈中从栈顶到栈底的顺序就是我们需要的顶点顺序。

上图表示原图G 的反向图GT。

我们现在进行第一种假设:假设DFS从位于强连通分量A 中的任意一个节点开始。那么第一次DFS完成后,栈中全部都是强连通分量A的顶点,第二次DFS完成后,栈顶一定是强连通分量B的顶点。保证了从栈顶到栈底的排序强连通分量B的顶点全部都在强连通分量A顶点之前。

我们现在进行第二种假设:假设DFS从位于强连通分量B 中的任意一个顶点开始。显然我们只需要进行一次DFS就可以遍历整个图,由于是逆后续遍历,那么起始顶点一定最后完成,所以栈顶的顶点一定是强连通分量B中的顶点,这显然是我们希望得到的顶点排序的结果。

上面使用了最简单的例子说明Kosaraju算法的原理,综上可得,不论从哪个顶点开始,图中有多少个强连通分量,逆后续遍历的栈中顶点的顺序一定会保证:被指向的强连通分量的至少一个顶点排在指向这个连通分量的所有顶点前面。
 

以下摘自算法第四版中的原文:

下图4.2.16所示为Kosaraju算法处理一幅有向无环图(右上角的图)时的轨迹。在每次dfs()调用轨迹的右侧都是有向图的一种画法,顶点按照搜索结束的顺序排列。因此,从下往上来看左侧这幅有向图的反向图得到的就是所有顶点的逆后序。也就是在原始的有向图中进行深度优先搜索时所有未被标记的顶点被检查的顺序。你可以从图中看到,在第二遍深度优先搜索中,首先调用的是dfs(1)(标记顶点1),然后调用的是dfs(0)(标记顶点0、5、4、3和2),然后检查了顶点2、4、5和3,再调用dfs(11)(标记顶点11、12、9和10),在检查了9、12和10之后调用dfs(6)(标记顶点6),最后调用dfs(7)标记了顶点7和8。最终得到了连通分量数量为5。

算法之有向图:强连通性与Kosaraju算法的全面解析 在编程学习的道路上,算法是解决复杂问题的核心工具,其重要性不言而喻。我在学习算法的过程中,遇到了不少难题,也积累了许多宝贵经验。深知独自面对算法知识时的迷茫,所以希望通过这篇博客,能与大家一起深入学习算法知识,在交流分享中共同进步,让更多人领略算法的魅力,提升编程技能。 阅读详情

相关推荐

图论中的强连通分量:Kosaraju算法详解

在图论的世界里,强连通分量(Strongly Connected Components, SCC)就像隐藏在有向图中的“小圈子”——圈子里的每个节点都能互相到达。无论是社交网络中的“死党群”、编译器中的“循环结构”,还是金融网络中的“欺诈闭环”,SCC都是理解复杂系统结构的关键。而Kosaraju算法则是挖掘这些“小圈子”的经典工具,它通过两次DFS遍历和逆图转换,以线性时间复杂度(O(V+E))高效解决SCC问题。

AI天才研究院 708

Kosaraju算法,超全解释

Kosaraju算法是一种用于寻找有向图强连通分量的经典算法。它由印度计算机科学家Sambasiva Kosaraju于1978年提出。在本文中,我将会详细介绍Kosaraju算法的原理、步骤以及实现方式,并对该算法进行性能分析和优化。

m0_72410588的博客 4742

有向图的强连通分量: Kosaraju算法和Tarjan算法详解

本文介绍强连通分量问题的解法, 主要介绍Kosaraju和Tarjan算法.

一些C++相关的技术笔记或者教程. 1909

C++的算法:Kosaraju算法与Tarjan算法

C++的算法:Kosaraju算法与Tarjan算法

全栈工程师Linda的博客 1271

图论算法入门:实用总结与应用案例

本文还有配套的精品资源,点击获取 简介:图论是计算机科学的关键领域,主要关注网络、路径寻找及最优化问题。本篇深入探讨图论的基础概念和重要算法,涵盖深度优先搜索、广度优先搜索、最短路径算法、最小生成树、拓扑排序、二分查找法、强连通分量分析、最大流最小割问题以及匹配理论。这些算法在路由选择、社交网络分析、电路设计、运输调度等多个实际领域中发挥着重要作用,对初学者而言是掌握更高级...

weixin_35734408的博客 2088

WinForm轻松打造AntDesign现代化工具栏

摘要: 本文介绍如何在WinForm中利用AntdUI库实现AntDesign风格工具栏,包括安装配置、动态生成按钮/下拉菜单、布局优化及主题美化。通过AntButton、AntDropdown等控件结合事件绑定,可快速构建支持图标、工具提示、权限控制的现代化工具栏,并解决常见图标加载、布局错乱问题。最后提供代码示例与响应式设计技巧,助你打造高效美观的WinForm界面。 (字数:150)

java专栏 1593

如何深入浅出的理解 Kosaraju

文章目录前言正题一些必要概念Kosaraju如和实现Why?如何理解问题 前言 今天想起来Kosaraju,网上关于这个算法的介绍比较少。(毕竟Tarjan太强了)。但是Tarjan和Kosaraju的复杂度都是O(n)O(n)O(n)的,Kosaraju的常数要大一点。(网上有的博客说kosaraju会卡爆栈,个人感觉不对,退化成链的情况Tarjan和Kosaraju都会一搜到底)。 那为什么Kosaraju常数大还要学它呢,用Tarjan不好吗? 因为它简单啊。毕竟Tarjan难理解是出了名的。 正题

Anadem‘s Blog 905

缠中说禅交易指南

战胜市场,其实就是战胜自己的贪婪、恐惧、愚蠢,缠中说禅技术分析理论只是把市场拔光给各位看,而拔光一个人并不意味着就等于征服一个人,对于市场,其道理是一样的。不干,不可能征服市场。对于市场来说,干就是一切。技术分析的最终意义不是去预测市场要干什么,而是分析市场正在干什么,是一种当下的直观。在市场上所有的错误都是离开了这当下的直观,用想象、用情绪来代替。 市场是有规律的,但市场的规律并不是显而易见的,是需要严格的分析才能得到。更重要的是,市场的规律是一种动态的,在不同级别合力作用下显示出来的规律,企图用些单纯的

baidu_25764509的博客 2万+

图综合练习--拓扑排序_图解:有向环、拓扑排序与Kosaraju算法

图算法第三篇 图解:有向环、拓扑排序与Kosaraju算法 首先来看一下今天的内容大纲,内容非常多,主要是对算法思路与来源的讲解,图文并茂,希望对你有帮助~1.有向图的概念和表示 概念有向图与上一篇文章中的无向图相对,边是有方向的,每条边所连接的两个顶点都是一个有序对,它们的邻接性都是单向的。 一幅有方向的图(或有向图)是由一组顶点和一组有方向的边组成的,每条有方向的边都连接着一对有序的顶点。...

weixin_39633954的博客 645

告别‘打架’的检测头:手把手教你用PyTorch实现YOLOv11解耦头(附完整代码)

本文详细解析了YOLOv11解耦检测头的创新设计与PyTorch实现,通过解耦分类和回归任务,显著提升目标检测性能。文章包含完整的代码实现、架构设计解析及工程调优技巧,帮助开发者深入理解并应用这一先进技术。

weixin_29031057的博客 301

华为OD机试 - 天然蓄水库(Java 2025 A卷 100分)

例如,当山脉为s = [3, 1, 2]时,则选取s[0]和s[2]作为水库边界,则蓄水量为1,此时输出:0 2:1。选取下标 0(高度 3)与 2(高度 2)为边界,水位为 min(3,2)=2;选取山脉上两个点作为蓄水库的边界,则边界内的区域可以蓄水,蓄水量需排除山脉占用的空间。经过分析,选取s[1]和s[6]时,水库蓄水量为19(3 + 7 + 4 + 5)。当存在合理的水库边界时,输出左边界、空格、右边界、英文冒号、蓄水量;当山脉`s = [3, 2, 1]时,不存在合理的边界,此时输出:0。

学Java,找哪吒 938

Kosaraju算法(强连通分量分解)

对于一个有向图顶点的子集S,如果在S内取两个顶点u和v,都能找到一条从u到v的路径,那么就称S是强连通的。如果在强连通的顶点集合S中加入其他任意顶点集合后,它都不再是强连通的,那么就称S是原图的一个强连通分量(SCC:strongly connected component)。任意有向图都可以分解成若不相干的强连通分量,这就是强连通分量分解。把分解后的强连通分量缩成一个顶点,就得到了一个DAG(有...

肘子的博客 9947

手把手教你学simulink(85.6)--非线性控制:滑模控制场景实例:基于Simulink建模仿真的滑模控制(Sliding Mode Control, SMC)在无人机自主飞行控制系统中的应用

首先,在MATLAB命令窗口中定义系统的参数和状态空间模型。matlab深色版本% 系统参数m = 1.5;% 无人机质量 (kg)g = 9.81;% 重力加速度 (m/s^2)% 惯性矩阵 (kg*m^2)% 初始条件pos0 = [0;0;0];% 初始位置 (m)vel0 = [0;0;0];% 初始速度 (m/s)0;0];% 初始姿态角 (rad)0;0];% 初始角速度 (rad/s)

MHD0815的博客 651

强连通分量(Korasaju、Tarjan)

常见的(我见过的)强连通分量的三种算法有:1. Kosaraju算法(双DFS)2.Tarjan算法 3.Gabow http://acm.hdu.edu.cn/showproblem.php?pid=1269 一.Kosaraju算法 算法的核心实现是,首先DFS一遍,得到一个DFS森林,在此过程中得到所有点的拓扑序列(按结束时间由高到低),之后我们建一个反向图,按反拓扑序(结束时间由

梦醒了 2589

鸿蒙ArkUI内部API10以及11开发,输入框唤起输入法键盘,页面会被顶起的解决办法

鸿蒙ArkUI内部API10以及11开发,输入框唤起输入法键盘,页面会被顶起的解决办法

zmx781284440的博客 3214

“/usr/lib/wsl/wsl-setup“ failed, exiting

WSL2安装Ubuntu时出现"wsl-setup failed"错误的解决方法 摘要:当Windows用户名包含中文字符时,安装WSL2+Ubuntu会出现"wsl-setup failed"错误。本文提供两种解决方案:1)修改中文用户名(风险较大);2)通过命令手动配置。推荐第二种方法:先使用"wsl -l -v"查看Ubuntu名称,再通过"wsl -d Ubuntu20.04 -e /bin/bash"命令启动WSL2系

猿小白的博客 995

强连通分量(kosaraju算法+Tarjian算法)

1、强连通:如果两个顶点u和v之间有u到v的路径,也有v到u的路径,则说明u和v强连通; 2、强连通图:有向图G中任何两个点之间都是强连通的; 3、强连通分量:有向非强连通图的极大联通子图称为强连通分量; 4、极大强连通子图:G是一个极大强连通子图,当且仅当G是一个强连通子图,且不存在另一个强连通子图G‘使得G是G’的真子集。   一、kosaraju算法 思路:(基于两次dfs有向连...

积少成多,水滴石穿 503

华为 MetaERP · 本体论驱动的 PTP 全流程智能建模方案

华为MetaERP通过“本体+事件+图谱+Agent”四位一体架构,将传统ERP从“记录系统”升级为“智能执行系统”。基于OWL本体实现业务语义精准表达,融合LLM与元数据多租能力,构建可推理、可治理的PTP全流程智能模型,解决AI理解业务逻辑难题,实现三单匹配自动化、关账效率提升30%、成本降低50%,推动企业数字化迈向可信智能新范式。

金牌架构师 181

C语言经典算法之Kosaraju算法

Kosaraju算法是用来寻找有向图的强连通分量的一种线性时间复杂度算法。

weixin_56154577的博客 1911

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

kosaraju算法

深入浅出的用Kosaraju算法计算得到有向图的强连通分量数

k的博客 2197

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

图的连通性(Kosaraju算法和Tarjan算法)

在一个图G中,对于任意两个顶点u和v,若u可以到达v,v也可以到达u,那么图G称为。如果该图为有向图,则称为。设顶点的集合V1为V的一个子集,若由V1构成的子图为连通图,则称V1为;如果在连通子图V1中加入其他任何一个顶点都不构成连通图,则称V1为。无向图的极大连通子图称为;有向图的极大连通子图称为。

qq_62687015的博客 829

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

强连通分量——kosaraju算法

kosaraju算法,三大强连通分量算法之一,最简单、最好理解的求解有向图强连通分量的方法,单纯的两次深搜,就可以划分我们的图。 算法流程: 1、从任意一个点开始深搜,得到图的一个最晚完成时间的排序; 2、求图的反图; 3、根据第1步得到的排序,从最晚完成的一个点开始搜索并染色; 4、第三步每一次深搜完成就是一个强连通分量。 下面进行算法的具体分析。 算法思想: 其实这个算法是由两

fuyukai的专栏 2858

Kosaraju算法详解

• Kosaraju算法是干什么的? Kosaraju算法可以计算出一个有向图的强连通分量 • 什么是强连通分量? 在一个有向图中如果两个结点(结点v与结点w)在同一个环中(等价于v可通过有向路径到达w,w也可以到达v)它们两 个就是强连通的,所有互为强连通的点组成了一个集合,在一幅有向图中这种集合的数量就是这幅图的强连通分量的数量 • 怎么算?? 第一步:计算出有向图 (G) 的反向...

weixin_33756418的博客 554

强连通分量(Tarjan、Kosaraju)

先介绍一下强连通分量: 首先,强连通分量只可能存在于有向图中,无向图中是不存在强连通分量的,当然,无向图中也有对应物,被称为连通分量,求解无向图中的连通分量,根据具体要求,可以选择使用并查集或者DFS。 对于一个强连通分量中的任意一对顶点(u,v),都能够保证分量中存在路径使得u->v,v->u看图: 以上用虚线围绕的部分就是一个强连通分量,因此上图中总共含有三个。上图中由a,b,e这三个顶点

zxw0819的博客 1121

图论 求有向图的所有强连通分量 kosaraju算法

一、问题 如何找到有向图(a)中的所有强连通分量,如图(b) 二、kosaraju算法 Kosaraju的算法(又称为–Sharir Kosaraju算法)是一个线性时间(linear time)算法找到的有向图的强连通分量。 1. 原理 它利用了一个事实,逆图(与各边方向相同的图形反转, transpose graph)有相同的强连通分量的原始图。 2. 逆图 将各边的方向反转 3. 算法图示 上图是对图G,进行一遍DFS(深度优先搜索)的结果, ...

软件工程小施同学 的专栏 3600

强连通分量之Kosaraju算法

今天学习了强连通分量的Kosaraju算法,网上写的人也不多,但是跟着视频教程讲解,还有去网上搜了博客,感觉他们的讲解都存在一定的问题,我在学习的时候碰到的一些困惑,他们并没有讲的清楚明白,当然,他们说的大致的思路是正确的。 算法思想: 先说说什么是强连通分量 强连通分量是针对有向图定义的,为了区别无向图的联通分量的概念。在一个强连通分量中,任意两点都相互可达。 这个图中就存在三个强连通分量,分...

weixin_42222609的博客 831
上一篇: Tarjan算法解析及Java代码实现(附图)
下一篇: Kruskal算法解析及Java代码实现(附图)
SpringRolls
博客等级 码龄9年 73粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值