理论: 图论(14):最大强连通图算法 tarjan

2023-05-16

最大强连通图定义

在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。

朴素算法

根据定义我们不难想到, 对同一张图同时进行正反两次遍历, 对两次的遍历结果取交集, 这里得到的便是强连通图。 在强连通图中寻找到度数最大的图即时最大强连通图。 同时的正反两次遍历我们不难发现他的时间复杂度达到了O(N ^ 2 + M)

tarjan算法

算法思想:

用dfs遍历G中的每个顶点,通dfn[i]表示dfs时达到顶点i的时间,low[i]表示i所能直接或间接达到时间最小的顶点。(实际操作中low[i]不一定最小,但不会影响程序的最终结果)

程序开始时,time初始化为0,在dfs遍历到v时,low[v]=dfn[v]=time++,
v入栈(这里的栈不是dfs的递归时系统弄出来的栈)扫描一遍v所能直接达到的顶点k,如果 k没有被访问过那么先dfs遍历k,low[v]=min(low[v],low[k]);如果k在栈里,那么low[v]=min(low[v],dfn[k])(就是这里使得low[v]不一定最小,但不会影响到这里的low[v]会小于dfn[v])。扫描完所有的k以后,如果low[v]=dfn[v]时,栈里v以及v以上的顶点全部出栈,且刚刚出栈的就是一个极大强连通分量。

大致证明过程

1.tarjan算法的基于定理:在任何深度优先搜索中,同一强连通分量内的所有顶点均在同一棵深度优先搜索树中。也就是说,强连通分量一定是有向图的某个深搜树子树。

2.dfs遍历时,如果已经遍历完v所能直接到达的顶点而low[v]=dfn[v],我们知道v一定能到达栈里v上面的顶点,这些顶点的low一定小于 自己的dfn,不然就会出栈了,也不会小于dfn[v],不然low [v]一定小于dfn[v],所以栈里v以其v以上的顶点组成的子图是一个强连通分量,如果它不是极大强连通分量的话low[v]也一定小于dfn[v](这里不再详细说),所以栈里v以其v以上的顶点组成的子图是一个极大强连通分量。

3.因为dfn保存的是深搜树的节点编号, 所以栈中下方的点一定可以到达上方, 而low保存的是这个节点向后(栈的下方)指的最大距离, 也就是向后反向边的最大距离。 我们说到栈中的节点正向可达, 拥有着一条反向边之后, 这个栈中的这个区间的元素就成了一个环, 变成了任意两点可达。 也就是我们所说的强连通, 又因为tarjan算法会遍历所有的点, 所以这里的强连通经过不断取最大之后, 得到的就是最大强连通分量。

时间复杂度

在这里每个点进一次栈, 每条边被遍历一次。 所以总的确定执行次数时n + m。 即O(N + M).

原始模板

void tarjan(int i)
{
    int j;
    DFN[i]=LOW[i]=++Dindex;
    instack[i]=true;
    Stap[++Stop]=i;
    for (edge *e=V[i];e;e=e->next)
    {
        j=e->t;
        if (!DFN[j])
        {
            tarjan(j);
            if (LOW[j]<LOW[i])
                LOW[i]=LOW[j];
        }
        else if (instack[j] && DFN[j]<LOW[i])
            LOW[i]=DFN[j];
    }
    if (DFN[i]==LOW[i])
    {
        Bcnt++;
        do
        {
            j=Stap[Stop--];
            instack[j]=false;
            Belong[j]=Bcnt;
        }
        while (j!=i);
    }
}
void solve()
{
    int i;
    Stop=Bcnt=Dindex=0;
    memset(DFN,0,sizeof(DFN));
    for (i=1;i<=N;i++)
        if (!DFN[i])
            tarjan(i);
}

动画演示

一下内容转自:https://www.byvoid.com/blog/scc-tarjan/

原始有向连通图:

这里写图片描述

从节点1开始DFS,把遍历到的节点加入栈中。搜索到节点u=6时,DFN[6]=LOW[6],找到了一个强连通分量。退栈到u=v为止,{6}为一个强连通分量。

这里写图片描述

返回节点5,发现DFN[5]=LOW[5],退栈后{5}为一个强连通分量。

这里写图片描述

返回节点3,继续搜索到节点4,把4加入堆栈。发现节点4向节点1有后向边,节点1还在栈中,所以LOW[4]=1。节点6已经出栈,(4,6)是横叉边,返回3,(3,4)为树枝边,所以LOW[3]=LOW[4]=1。

这里写图片描述

继续回到节点1,最后访问节点2。访问边(2,4),4还在栈中,所以LOW[2]=DFN[4]=5。返回1后,发现DFN[1]=LOW[1],把栈中节点全部取出,组成一个连通分量{1,3,4,2}。

这里写图片描述

至此,算法结束。经过该算法,求出了图中全部的三个强连通分量{1,3,4,2},{5},{6}。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

理论: 图论(14):最大强连通图算法 tarjan 的相关文章

  • 点乘和叉乘

    向量点乘 xff08 内积 xff09 和叉乘 xff08 外积 向量积 xff09 向量 向量是由n个实数组成的一个n行1列 xff08 nX1 xff09 或一个1行n列 xff08 1Xn xff09 的有序数组 xff1b 点乘 向
  • ​​Linux下ps -ef和ps aux的区别及格式详解​

    Linux下显示系统进程的命令ps xff0c 最常用的有 ps ef 和 ps aux 这两个到底有什么区别呢 xff1f 两者没太大差别 xff0c 讨论这个问题 xff0c 要追溯到Unix系统中的两种风格 xff0c System
  • Windows命令行操作

    打开 win 43 r然后输入cmd回车 命令 cd进入命令 dir显示命令

随机推荐

  • JDK源码之-java.lang.Object

    JDK源码之 java lang Object public final native Class lt gt getClass public native int hashCode public boolean equals Object
  • Docker安装Elasticsearch的遇到的那些坑

    1 根据百度到的一篇文章 https segmentfault com a 1190000004376504 下载其最新镜像 hangxin1940 docker elasticsearch cn v2 1 0 使用 docker run
  • APScheduler Execution of job “***“ skipped: maximum number of running instances reached (1)

    错误原因 有错误提示所说 xff0c 因为超过了最多实例个数 xff0c APScheduler的默认最大实例个数为1 xff0c 导致之后任务调用阻塞 xff0c 无法进行执行 解决办法 提高代码效率 xff0c 缩短代码运行时间 延长定
  • Spring boot + Spring Security + Thymeleaf 认证失败返回错误信息

    Spring boot 43 Spring Security 43 Thymeleaf 认证失败返回错误信息 Spring boot以其众多友谊的特性 xff0c 如零配置 微服务等 xff0c 吸引了很多的粉丝 而其与Spring Sec
  • Java经典面试题(其三)——JVM原理和调优

    Java经典面试题 xff08 其三 xff09 JVM原理和调优 一 什么是JVM JVM是Java Virtual Machine xff08 Java虚拟机 xff09 的缩写 xff0c JVM是一种用于计算设备的规范 xff0c
  • Spring Boot Starter的面试题

    Spring Boot Starter的面试题 1 常见的starter会包几个方面的内容 xff1f 分别是什么 xff1f span class hljs comment 常见的starter会包括下面四个方面的内容 span span
  • 个人经历:谈一谈的程序员求职途径

    个人经历 xff1a 谈一谈的程序员求职途径 互联网招聘网站的确是五花八门 xff0c 种类繁多 xff0c 在投递简历 xff0c 接听面试电话的过程中 xff0c 要擦亮眼睛 xff0c 慎重选择和沟通 我是去年跳槽的 xff0c 下面
  • JVM调优再学习

    JVM调优再学习 堆大小设置 JVM中最大堆大小有三方面限制 xff1a 相关操作系统的数据模型 xff08 32 bit还是64 bit xff09 限制 xff1b 系统的可用虚拟内存限制 xff1b 系统的可用物理内存限制 32位系统
  • Dubbo源码学习基础

    dubbo源码学习基础 Dubbo源码学习基础Java RMI 基本概念在 Dubbo 中使用注解自定义容错策略正确加载MyFilter类Dubbo可扩展机制实战Dubbo的SPI机制自定义一个LoadBalance扩展Dubbo 外部化配
  • ubuntu中Terminal消失

    Terminal不见了 安装Python 3 6 在Ubuntu 16 04 LTS 版本 警告 xff1a 在根据下面文章操作之后 xff0c 电脑终端关上之后再也打不开 xff0c 因为同时修改了很多东西 xff0c 所以排查了好久才找
  • MacVim学习总结

    Emacs和Vim都是程序员专用编辑器 xff0c Emacs被称为神的编辑器 xff0c Vim则是编辑器之神 至于两者到底哪个更好用 xff0c 网络上两大派系至今还争论不休 不过 xff0c 相比之下 xff0c Emacs更加复杂
  • Passbook对应系统配置 Eclipse Tomcat配置JavaWeb项目部署 Sysdeo Eclipse Tomcat Launcher plugin

    在 Eclipse J2EE Juno 43 Tomcat 6 用Tomcat Plugin配置Tomcat 应用时 xff0c 不想Copy一堆 jar文件到应用的lib目录中 xff0c 应该可以用Activate DevLoader在
  • Ubuntu或CentOS下Python源码安装,以及需要的依赖包,pip修复安装

    准备环境 依赖包 span class token function sudo span span class token function apt get span y update span class token operator a
  • Seasar2 框架学习笔记

    基本Seasar2 Web应用工程结构 Seasar2这个框架在日本十分的流行 Seasar2其实就是类似于Spring的一个提供DI功能的开源框架 xff0c 但比Sping轻量级 并且同 其它轻量级容器 不同的是 xff0c 完全不需要
  • Struts Tiles框架,标签库详解<tiles:insert page="facebook.jsp" />

    Tiles框架为创建Web页面提供了一种模板机制 xff0c 它能将网页的布局和内容分离 它允许先创建模板 xff0c 然后在运行时动态地将内容插入到模板中 Tiles 框架建立在JSP的include指令的基础上 xff0c 但它提供了比
  • 解决:弹出“Building workspace has encountered a problem. Error 方法

    开发过程中常遇到这种情况 xff0c 在打开eclipse的时候 xff0c 弹出对话框 xff0c 提示 Building workspace has encountered a problem Errors during build 解
  • flexpaper实现文档的在线预览

    在把文档的格式转换成swf格式以后 xff0c 现在该实现在线的预览 在线预览的方法有两种方式 第一种 xff1a 通过flashpaper实现文档的在线预览 第二种是通过flexpaper实现文档的在线预览 在博客中用到的是第二种方法 在
  • MySql可视化工具MySQL Workbench使用教程

    1 MySQL Workbench MySQL Workbench 为数据库管理员 程序开发者和系统规划师提供可视化的Sql开发 数据库建模 以及数据库管理功能 2 MySQL Workbench 的下载和安装 xff08 1 xff09
  • MAC OS命令行使用详解

    原文地址 xff1a http www renfei org blog mac os x terminal 101 html 最近学习苹果认证的 Mac OS X Support Essentials 教程 xff0c 看到 Command
  • 理论: 图论(14):最大强连通图算法 tarjan

    最大强连通图定义 在有向图G中 xff0c 如果两个顶点间至少存在一条路径 xff0c 称两个顶点强连通 strongly connected 如果有向图G的每两个顶点都强连通 xff0c 称G是一个强连通图 非强连通图有向图的极大强连通子