图论——强连通分量:Tarjan算法。

简介: 在有向图G中,如果两个定点u,v间存在一条u到v的路径,也存在一条v到u的路径,则称u,v是强连通的。若有向图G的任意两点都强联通,则称G是一个强联通图。非强连通图的极大强连通子图称为强连通分量。 这里,极大强连通子图可以理解为一个子图是强连通图,且它的任意子图都不是强联通。

在有向图G中,如果两个定点u,v间存在一条u到v的路径,也存在一条v到u的路径,则称u,v是强连通的。

若有向图G的任意两点都强联通,则称G是一个强联通图。

非强连通图的极大强连通子图称为强连通分量。

 

这里,极大强连通子图可以理解为一个子图是强连通图,且它的任意子图都不是强联通。

 

我们来看下面几张图。

 

这是强连通图。

 

这是强连通分量。

一个非强连通图中,可以有多个强连通分量。

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·

在考试中,遇到有强连通分量时,可以将他们缩成一个点,使原图其变成有向无环图(DAG),求解问题就方便了。

 

再看一个栗子:

 

 

这就很神奇了。

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 Tarjan算法

 

Tarjan算法主要是基于DFS搜索树。每一个强连通分量都是搜索树中的一颗紫薯子树

在利用数据结构——栈,将当前搜索树中未处理的节点入栈,回溯时即可判断是否构成强连通分量。

 

算法过程:

Tarjan算法需要维护两个数组:Dfn(节点被访问的时间,又叫时间戳),Low(回溯时能够回溯到最小的Dfn值)。

1.当首次遍历节点u时,dfn [ u ] = low [ u ] ;

2.u入栈,更新low [ u ];

3.遍历与u相邻的边(u , v),

若v不在栈中,u是v的父节点,low [ u ] = min ( low [ u ] , low [ v ] );

若v在栈中, low [ u ] = min ( low [ u ] , dfn [ v ] );

4.在u的子树都遍历完了之后,若low [ u ] = dfn [ u ],则栈顶到u之间(包括栈顶以及u)的元素组成了一个强连通分量。

5.继续搜索

 

让我们来手动模拟一下Tarjan

 

1.从0开始dfs

2.将顶点 0 的 dfn 0 ​ 和low 0 ​ 都设置为当前时间戳 1

 

 3.接下来访问相邻未访问的顶点 1,将 dfn 1 ​ 和 low 1 ​ 都设置为当前时间戳 2。

4.接下来访问相邻未访问顶点 3,将dfn 3 ​ 和 low 3 ​ 都设置为当前时间戳 3

5.没有其他相邻顶点,此时 dfn 3 ​ =low 3 ​ ,故将 3 出栈作为一个强连通分量。

6.同样地,因为dfn 1 ​ =low 1 ​ ,所以将 1 出栈作为一个强连通分量。

7.继续访问和 0 相邻的其他顶点 2,将 dfn 2 ​ 和 low 2 ​ 都设置为当前的时间戳 4

8.访问相邻顶点 4,将 dfn 4 ​ 和 low 4 ​ 都设置为当前的时间戳 5。

9.访问相邻顶点 5,将 dfn 5 ​ 和low 5 ​ 都设置为当前的时间戳 6。

10.发现此时有指向栈中元素 1 的边,将 low 5 ​ 更新为 dfn 0 ​ =1。

11.回溯到顶点 4,用low 5 ​ 更新low 4 ​ ,更新为 1。

12.回溯到顶点 2,用 low 4 ​ 更新low 2 ​ ,更新为 1。

13.顶点 2 有一个在栈中的相邻顶点 5,用 dfn 5 ​ 更新 low 2 ​ ,不发生任何变化

14.回溯到顶点 0,用 low 2 ​ 更新 low 0 ​ 。此时发现 low 0 ​ =dfn 0 ​ ,将栈中元素弹出作为一个新的强连通分量。

15.找到下一个未访问的顶点 6,设置dfn 6 ​ =low 6 ​ =7。

16.发现顶点 6 没有指向栈中元素的边,搜索结束,将 6 作为一个新的强连通分量。

17.计算结束,{3},{1},{0,2,4,5},{6} 是图中的四个强连通分量。

 

好不容易,终于码完了。

 

那么,理解了思路,我们就来看看代码。

 

code of Tarjan:

 

 1 stack<int>s;
 2 int dfn[10001],low[10001],sum;
 3 void tarjan(int u){
 4     dfn[u]=low[u]=++sum;
 5     s.push(u);
 6     visit[u]=true;
 7     for(int i=head[u];~i;i=edg[i].nxt){
 8         if(!dfn[edg[i].to]){
 9             tarjan(edg[i].to);
10             low[u]=min(low[u],low[edg[i].to]);
11         }
12         else if(visit[edg[i].to])low[u]=min(low[u],dfn[edg[i].to]);
13     }
14     if(low[u]==dfn[u]){
15         int j;
16         sumscc++;
17         do{
18             j=s.top();
19             s.pop();
20             visit[j]=false;
21             scc[sumscc]++;
22             belong[j]=sumscc;
23         }while(j!=u);
24     }
25 }

这就是Tarjan算法,下次我们将通过习题再来深究Tarjan算法

 

祝大家NOIP rp++

 

相关文章
|
7月前
|
机器学习/深度学习 安全 算法
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
|
29天前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
|
7月前
|
算法 Python
Python中实现图论算法
Python中实现图论算法 “【5月更文挑战第20天】”
49 3
|
6月前
|
算法 数据挖掘 定位技术
算法必备数学基础:图论方法由浅入深实践与应用
算法必备数学基础:图论方法由浅入深实践与应用
|
7月前
|
人工智能 算法 BI
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
|
7月前
|
机器学习/深度学习 算法 测试技术
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
|
7月前
|
安全 算法 测试技术
【图论】【并集查找】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【并集查找】【C++算法】928. 尽量减少恶意软件的传播 II
|
19天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
25天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
5天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。