当前位置: 首页 > news >正文

【数据结构(邓俊辉)学习笔记】图04——双连通域分解

文章目录

  • 0. 概述
  • 1 关节点与双连通域
  • 2 蛮力算法
  • 3 可行算法
  • 4 实现
  • 5 示例
  • 6 复杂度

0. 概述

学习下双连通域分解,这里略微有一点点难,这个算是DFS算法的非常非常经典的应用,解决的问题也非常非常有用。

1 关节点与双连通域

连通性很好理解,两个点在图中只要有一条路径,不管是无向的还是有向的,只要互相可达,就说他们是连通的。但有的时候会要求更严些,不仅要保证自己和某些地方的连通,还要保证某个区域不会变成独立的,另一个角度可以从关节点来理解。
在这里插入图片描述
明确下几个术语

考查无向图G。若删除顶点v后G所包含的连通域增多,则v称作切割节点(cut vertex)或关节点(articulation point)。
~  
如图C即是一个关节点——它的删除将导致连通域增加两块。反之,不含任何关节点的图称作双连通图。任一无向图都可视作由若干个极大的双连通子图组合而成,这样的每一子图都称作原图的一个双连通域(bi-connected component)。
~  
例如右上图中的无向图,可分解为右下图所示的三个双连通域。

任何一张连通的无向图都存在着若干个关键点,而且以这些关键点为界,可以将其分割为若干个双连通部分——BCC分量。

较之其它顶点,关节点更为重要。在网络系统中它们对应于网关,决定子网之间能否连通。在航空系统中,某些机场的损坏,将同时切断其它机场之间的交通。故在资源总量有限的前提下,找出关节点并重点予以保障,是提高系统整体稳定性和鲁棒性的基本策略。

那么怎么计算?给一个任意的图,如何将其分解为一个一个又一个BCC分量呢?作为查找结果的副产品——关键点,怎么得到?

2 蛮力算法

由其定义,可直接导出蛮力算法大致如下:

  1. 首先,通过BFS或DFS搜索统计出图G所含连通域的数目;
  2. 然后逐一枚举每个顶点v,暂时将其从图G中删去,并再次通过搜索统计出图G{v}所含连通域的数目。
  3. 于是,顶点v是关节点,当且仅当图G{v}包含的连通域多于图G。
    在这里插入图片描述
    这一算法需执行n趟搜索,耗时O(n(n + e)),如此低的效率无法令人满意。

3 可行算法

经DFS搜索生成的DFS树,表面上看似乎“丢失”了原图的一些信息,但实际上就某种意义而言,依然可以提供足够多的信息。

  • 先分析下根节点 情况
    在这里插入图片描述

DFS树中的叶节点,绝不可能是原图中的关节点

此类顶点的删除既不致影响DFS树的连通性,也不致影响原图的连通性。

此外,DFS树的根节点若至少拥有两个分支,则必是一个关节点。

如上图,在原无向图中,根节点R的不同分支之间不可能通过跨边相联(算法中为什么讨论cross edge?因为讨论的是有向图),R是它们之间唯一的枢纽。
~  

因此,这里也得出个结论:在无向图的DFS中是不可能有cross edge和forward edge,只有back word 回向边
~  
反之,若根节点仅有一个分支,则与叶节点同理,它也不可能是关节点。

  • 那么,又该如何甄别一般的内部节点是否为关节点呢?
    在这里插入图片描述
    考查上图中的内部节点C。若节点C的移除导致其某一棵(比如以D为根的)真子树与其真祖先(比如A)之间无法连通,则C必为关节点。反之,若C的所有真子树都能(如以E为根的子树那样)与C的某一真祖先连通,则C就不可能是关节点。

以D为根的真子树经过一系列访问后,会生成一系列tree edge和back edge,关键在于back edge。形象来说,若back edge往上指的不是那么高,准确来讲,不会高过父亲C,则C就是关键点。因为C若消失,则以D为根的真子树就会变成孤岛。

当然,在原无向图的DFS树中,C的真子树只可能通过后向边与C的真祖先连通。因此,只要在DFS搜索过程记录并更新各顶点v所能(经由后向边)连通的最高祖先(highest connected ancestor, HCA)hca[v],即可及时认定关节点,并报告对应的双连通域。

以E为根的真子树中的back edge往上指的更高,准确来讲,高过父亲C,则C就不是关键点。因为C若消失,则以E为根的真子树也会通过back edge保持连通。

因此通过遍历需要得到很重要指标 dTime 和 HCA,算法大体框架

  • 由括号引理: dTime越小的祖先,辈份越高
  • DFS过程中,一旦发现后向边(v,u) ~~~~      即取:hca(v) = min( hca(v) , dtime(u) )
  • DFS(u) 完成并返回v时 ~~~~      若有:hca(u) < dTime(v) ~~~~      即取:hca(v) = min( hca(v), hca(u) ) ~~~~      否则,即可判定:v系关节点,且 {v} + subtree(u) 即为一个BCC。
  • 那么如何实现?

4 实现

在这里插入图片描述
算法来看就是典型的DFS,这里改个名字叫BCC,这里利用闲置的fTime充当hca。

  • 看下u分别有哪些状态需要处理?
    首先看下UNDISCOVERED状态,既tree edge
    在这里插入图片描述
    在从顶点u处深入到遍历返回后之间的代码逻辑与DFS几乎一致,当遍历返回后,v的hca便已确定。故DFS搜索在顶点v的孩子u处返回之后,通过比较hca[u]与dTime[v]的大小,即可判断v是否关节点。
  1. 若hca[u] ≥ dTime[v],则说明u及其后代无法通过后向边与v的真祖先连通,故v为关节点。既然栈S存有搜索过的顶点,与该关节点相对应的双连通域内的顶点,此时都应集中存放于S顶部,故可依次弹出这些顶点。v本身必然最后弹出,作为多个连通域的联接枢纽,它应重新进栈。
  2. 反之若hca[u] < dTime[v],则意味着u可经由后向边连通至v的真祖先。果真如此,则这一性质对v同样适用,故有必要将hca[v],更新为hca[v]与hca[u]之间的更小者。

再看下DISCOVERED 和VISITED(这个状态只有有向边才有,这里可不关注,只是为了和DFS作对比)

在这里插入图片描述
当然,每遇到一条后向边(v, u),也需要及时地将hca[v],更新为hca[v]与dTime[u]之间的更小者,以保证hca[v]能够始终记录顶点v可经由后向边向上连通的最高祖先。

5 示例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6 复杂度

与基本的DFS搜索算法相比,这里只增加了一个规模O(n)的辅助栈,故整体空间复杂度仍为O(n + e)。时间方面,尽管同一顶点v可能多次入栈,但每一次重复入栈都对应于某一新发现的双连通域,与之对应地必有至少另一顶点出栈且不再入栈。因此,这类重复入栈操作不会超过n次,入栈操作累计不超过2n次,故算法的整体运行时间依然是O(n + e)。

相关文章:

【数据结构(邓俊辉)学习笔记】图04——双连通域分解

文章目录 0. 概述1 关节点与双连通域2 蛮力算法3 可行算法4 实现5 示例6 复杂度 0. 概述 学习下双连通域分解&#xff0c;这里略微有一点点难&#xff0c;这个算是DFS算法的非常非常经典的应用&#xff0c;解决的问题也非常非常有用。 1 关节点与双连通域 连通性很好理解&am…...

UI学习(二)

UI学习&#xff08;二&#xff09; 文章目录 UI学习&#xff08;二&#xff09;布局子视图手动布局自动布局 导航控制器导航控制器基础导航控制器的切换导航栏工具栏 分栏控制器分栏控制器协议部分的内容UITableView基础部分相关的协议函数高级协议与单元格 多界面传值 布局子视…...

【嵌入式】波特率9600,发送8个字节需要多少时间,如何计算?

问题&#xff1a; 波特率9600&#xff0c;发送 01 03 00 00 00 04 44 09 (8字节) 需要多少时间&#xff0c;如何计算&#xff1f; 在计算发送数据的时间时&#xff0c;首先要考虑波特率以及每个字符的数据格式。对于波特率9600和标准的UART数据格式&#xff08;1个起始位&…...

jmeter -n -t 使用非GUI模式运行脚本说明

命令模式下执行jmx文件 jmeter -n -t fatie.jmx -l results\t4.jtl -e -o results\h1 表示以命令行模式运行当前目录下的脚本fatie.jmx,将结果存入当前目录下的results\t1.jtl,并且生成html格式的报告&#xff0c;写入文件夹results\h1。 说明&#xff1a;生成结果的文件夹r…...

网络流媒体协议——HLS协议

HTTP 实时流媒体&#xff08;HTTP Live Streaming&#xff0c;HLS&#xff09;协议是苹果公司提出的主要用于直播的流媒体协议。一个完整的基于HLS协议的流媒体直播系统由四部分组成&#xff0c;即音视频采集器、媒体服务器、媒体分发器和播放客户端。 媒体服务器 媒体服务器的…...

Linux服务器扩容及磁盘分区(LVM和非LVM)

Linux扩容及磁盘分区&#xff08;LVM和非LVM&#xff09; 本文主要介绍了阿里云服务器centos的扩容方法&#xff1a;非LVM分区扩容方法&#xff08;系统盘&#xff09;&#xff0c;以及磁盘改LVM并分区&#xff08;数据盘&#xff09;。主要是ext4文件系统及xfs磁盘scsi MBR分…...

支持向量机

支持向量机&#xff08;SVM&#xff09; 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种用于分类和回归任务的监督学习算法。SVM 的核心思想是找到一个最优的决策边界&#xff08;或称为超平面&#xff09;&#xff0c;以最大化不同类别之间的间隔。以…...

Kafka 架构

1 整体架构 1.1 Zookeeper Zookeeper 是一个分布式协调服务&#xff0c;用于管理 Kafka 的元数据。它负责维护 Kafka 集群的配置信息、Broker 列表和分区的 Leader 信息。 Zookeeper 确保了 Kafka 集群的高可用性和可靠性。 但 Zookeeper 已经成为 Kafka 性能瓶颈&#xff0c;…...

iOS 查看runtime源码的几种方法

目录 前言 查看runtime 源码方法 1.下载 Apple 官方提供的源代码 2.通过 GitHub 访问镜像 3.使用命令行工具查看 4.示例 前言 这篇博客主要介绍了查看iOS runtime源代码的方法。 查看runtime 源码方法 查看iOS runtime源码的方法包括以下几个步骤&#xff1a; 1.下载 A…...

底板外设倒灌到处理器分析

在嵌入式系统中&#xff0c;底板外设通常与处理器通过各种接口&#xff08;如UART、SPI、I2C、GPIO等&#xff09;进行连接。这些外设可能包括传感器、执行器、存储器、通信模块等。倒灌是指当外设向处理器提供的信号电平超出了处理器能够接受的范围&#xff0c;导致处理器无法…...

使用贝塞尔曲线实现一个iOS时间轴

UI效果 实现的思路 就是通过贝塞尔曲线画出时间轴的圆环的路径&#xff0c;然后 使用CAShaper来渲染UI&#xff0c;再通过 animation.beginTime [cilrclLayer convertTime:CACurrentMediaTime() fromLayer:nil] circleTimeOffset 来设置每个圆环的动画开始时间&#xff0c; …...

【深度学习】深度学习之巅:在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境

【深度学习】深度学习之巅&#xff1a;在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境 大家好 我是寸铁&#x1f44a; 总结了一篇【深度学习】深度学习之巅&#xff1a;在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境✨ 喜欢的小伙伴可以点点关注 &#…...

在docker容器中使用gdb调试python3.11的进程

gdb调试python进程的前提条件 安装python及python调试信息安装gdb工具安装python-gdb.py扩展 安装过程 我们使用docker来安装以上内容&#xff0c;Dockerfile文件内容如下&#xff1a; FROM docker.io/centos:7.4.1708# 安装依赖 RUN yum install -y -q epel-release &…...

堆排序要点和难点以及具体案例应用

堆排序(Heap Sort)是一种基于堆数据结构的排序算法。下面我将以分点表示和归纳的方式,结合相关数字和信息,详细描述堆排序的PTA(Programming and Testing Approach,编程与测试方法)。 1. 堆排序原理 堆排序是一种树形选择排序,利用了完全二叉树的性质,通过构建最大堆…...

pyspark中使用mysql jdbc报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver解决

报错信息&#xff1a; py4j.protocol.Py4JJavaError: An error occurred while calling o33.load. : java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 我的解决方法&#xff1a; 这个报错就是提示你找不到jar包&#xff0c;所以你需要去下载一个和你mysql版本匹配的j…...

对称加密系统解析

目录​​​​​​​ 1.概述 2. 对称密码类型 3. 对称加密优缺点 4. 对称加密算法 4.1 DES 4.2 3DES 4.3 AES ​​​​​​4.4 SM1 4.5 SM4 1.概述 对称加密&#xff0c;是指在加密和解密时使用同一秘钥的方式。秘钥的传送和保存的保护非常重要&#xff0c;务必不要让秘…...

初识 java 2

1. idea 的调试 1. 点击鼠标左键设置断点 2.运行到断点处 点击 或点击鼠标右键&#xff0c;再点击 使代码运行到断点处&#xff0c;得到 2. 输出到控制台 System.out.println(value);//输出指定的内容&#xff0c;并换行 value 要打印的内容System.out.print(value);…...

云端狂飙:Django项目部署与性能优化的极速之旅

Hello&#xff0c;我是阿佑&#xff0c;这次阿佑将手把手带你亲自踏上Django项目从单机到云端的全过程&#xff0c;以及如何通过Docker实现项目的无缝迁移和扩展。不仅详细介绍了Docker的基本概念和操作&#xff0c;还深入探讨Docker Compose、Swarm和Kubernetes等高级工具的使…...

GDPU JavaWeb 大结局篇(持续更新中)

GDPUJavaWeb程序设计复习&#xff0c;习题集&#xff0c;重点知识总结&#xff0c;一篇就够了。 实验复习 JavaWeb代码复习&#xff0c;在专栏也可查阅。 课后巩固习题 1 【单选题】下列说法正确的是( D ) A、在B/S结构中,结果应用软件发生了改变,就必须通知所有的客户端重新…...

Linux系统信息的查看

目录 前言一、系统环境二、查看系统IP地址信息2.1 ifconfig命令2.2 ip address命令 三、查看系统端口信息3.1 nmap命令3.2 netstat命令 四、查看系统进程信息4.1 ps命令4.2 kill命令 五、查看系统监控信息5.1 top命令5.2 df命令iostat命令5.3 sar命令 总结 前言 本篇文章介绍查…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...