无向图的点、边双连通分量

文章目录

  • 点双连通分量
  • 边双连通分量

有向图的强连通分量:寒假学习笔记【匠心制作,图文并茂】——1.20拓扑、强连通分量、缩点

点双连通分量

在这之前,先让我们了解几个概念。

  • 割点:删除一个点和其连出的边后,原图会裂为多个不连通的部分,这个点叫做割点。
  • 点双连通分量(v-dcc,简称点双):极⼤不含割点的连通⼦图(和强连通分量的定义很像)。

OK,现在让我们进入正题:求点双连通分量。

其实,我们不难想到,既然点双是极大不含割点的连通子图,那么两个割点之间的部分应该就是一个点双,而割点本身则属于多个点双,那怎么找割点呢?

我们顺着强连通分量的想法往下,如果我们先跑了一遍 tarjan,那么我们就会得到每个点的 lowdfn 值,那对于一个点双它肯定长这样:

这说明了什么?说明割点的子节点是无法通过其他边与上面的点相连的,否则这个点就不是割点了,这说明割点的 low 值应该大于等于其 dfn 值,因为越往上,dfn 值就越小,low 值也就越小,只有在上面那种情况下 low 值才会大于等于 dfn 值。

当然,在上述情况中还有几个特例,例如目前搜查的这个点没有父亲节点(即根节点),那就要看满足上述条件的子树有多少个,如果只有一个,那它也不是割点,否则就是。而对于其他点,因为它们都有儿子节点与父亲结点,所以只要有满足上述条件的子树就行,不用管多少个。

找到割点了,现在该找点双了。很明显,割点及其子节点就是一个点双,而按照强连通分量的做法,一个点的子节点都会被保存在栈中,所以我们只需要一直弹出栈顶,直到弹到割点就行了。

注意,我们前面说过:一个割点属于多个点双。所以我们在把割点弹出之后还要再放回栈中。

还有一种方案,就是我们不弹出割点,直接手动加上割点就行了。

核心代码如下:

vector<int>v[N];
stack<int>st;
void v_dcc(int u,int fa)
{dfn[u]=low[u]=++ti;if(u==rt&&v[u].size()==0)//一个点自成点双{cnt++;vdcc[cnt].emplace_back(u);return;}st.emplace(u);int son=0,sum=0;for(auto i:v[u]){if(i==fa){sum++;//解决重边问题if(sum==1){continue;}}if(!dfn[i]){dfs(i,u);low[u]=min(low[u],low[i]);if(dfn[u]<=low[i])//因为割点可能有多个子树,所以每扫到一个子树就要算一遍{son++;if(son==1&&u!=rt||son>=2){cut[u]=true;//判断割点}cnt++;while(!st.empty()){int x=st.top();st.pop();vdcc[cnt].emplace_back(x);if(x==i){break;}}vdcc[cnt].emplace_back(u);//割点属于多个点双}}else{low[u]=min(low[u],dfn[i]);}}
}

边双连通分量

同样,在这之前,先了解几个概念:

  • 桥:断开后会让图分裂成两个不连通的部分的线。
  • 边双连通分量(e-dcc,简称边双):极大不含桥的联通子图。

和上面的点双类似,边双也是在强联通分量的做法的基础上改进的,我们先画一个边双模版:

很显而易见了,如果一条边是一个桥,那么它以下的子树都无法通过别的边与上面向连通。

那么我们假设边 (x,y) 是一个桥(x 在 y 上面),根据上面的性质就可以很轻松的得出 dfn[x]<low[y],因为上下不连通的嘛,所以下面的 low 值肯定会比上面的 dfn 值还大。

通过桥,我们可以找到第一种找 e-dcc 的方法:把所有的桥全部断开,剩下的就是 e-dcc,不过难度有亿点大。

现在让我们回想上面对于桥的性质的描述:

如果一条边是一个桥,那么它以下的子树都无法通过别的边与上面向连通。

这是不是很想我们讲强连通分量里面的一句话:

我们假设一个节点与它的子树形成了一个 SCC,那么它以及它的所有子树都不会通过返祖边与横叉边与其他点相连,而且一定会有返祖边与这个根节点相连。

难道说,找 e-dcc 和找 SCC 有什么本质上的联系吗?

答案是有。根据桥的性质我们可以知道:一个桥以下的子树的 low 是等于最顶上那个节点的 dfn 的(都分析了那么多遍了,这次应该自己看得懂了吧)。这跟 SCC 的求法几乎一模一样!

因此,我们就可以写出代码。

当然最后说一点:因为原图是一个无向图,所以并不存在前向边和横叉边,因为这些边都会通过一系列转化变成返祖边,因此 ins 数组就可以省去,因为所有的边被换成返祖边了之后,那些“祖先们”肯定只能和它下面的点形成 e-dcc,也就不存在会被提前“收服”的情况了。

核心代码如下:

vector<int>v[N],edcc[N];
stack<int>st;
void e_dcc(int x,int fa)
{dfn[x]=low[x]=++ti;st.emplace(x);int sum=0;for(auto i:v[x]){if(i==fa){sum++;if(sum==1)//判重边{continue;}low[x]=min(low[x],dfn[fa]);//否则更新}if(!dfn[i]){e_dcc(i,x);low[x]=min(low[x],low[i]);}else//不必再判{low[x]=min(low[x],dfn[i]);}}if(low[x]==dfn[x]){cnt++;while(1){int u=st.top();st.pop();edcc[cnt].emplace_back(u);if(u==x){break;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第六十二节:深度学习-加载 TensorFlow/PyTorch/Caffe 模型

在计算机视觉领域,OpenCV的DNN(深度神经网络)模块正逐渐成为轻量级模型部署的利器。本文将深入探讨如何利用OpenCV加载和运行三大主流框架(TensorFlow、PyTorch、Caffe)训练的模型,并提供完整的代码实现和优化技巧。 一、OpenCV DNN模块的核心优势 OpenCV的DNN模块自3.3…

Spring @Autowired自动装配的实现机制

Spring Autowired自动装配的实现机制 Autowired 注解实现原理详解一、Autowired 注解定义二、Qualifier 注解辅助指定 Bean 名称三、BeanFactory&#xff1a;按类型获取 Bean四、注入逻辑实现五、小结 源码见&#xff1a;mini-spring Autowired 注解实现原理详解 Autowired 的…

胜牌™全球成为2026年FIFA世界杯™官方赞助商

胜牌全球将首次与国际足联&#xff08;FIFA&#xff09;旗舰赛事建立合作关系。 此次赞助恰逢美国首个润滑油品牌即将迎来160周年之际&#xff0c;其国际扩张步伐正在加快。 在这项全球顶级赛事筹备期间&#xff0c;胜牌全球将通过各种富有创意的零售和体验活动与球迷互动。 …

YOLOV7改进之融合深浅下采样模块(DSD Module)和轻量特征融合模块(LFI Module)

目录 一、研究背景​ 二. 核心创新点​ ​2.1 避免高MAC操作​ ​2.2 DSDM-LFIM主干网络​ 2.3 P2小目标检测分支​ ​3. 代码复现指南​ 环境配置 关键修改点 ​4. 实验结果对比​ 4.1 VisDrone数据集性能 4.2 边缘设备部署 4.3 检测效果可视化 ​5. 应用场景​ …

【C/C++】chrono简单使用场景

chrono使用场景举例 1 输出格式化字符串 示例代码 auto now std::chrono::system_clock::now(); auto t std::chrono::system_clock::to_time_t(now); auto ms std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;std::ostrin…

Med-R1论文阅读理解-1

论文总结&#xff1a;Med-R1: Reinforcement Learning for Generalizable Medical Reasoning in Vision-Language Models 论文写了什么&#xff1f; 本文提出了一种名为 Med-R1 的新框架&#xff0c;旨在通过强化学习&#xff08;Reinforcement Learning, RL&#xff09;提升…

京东热点缓存探测系统JDhotkey架构剖析

热点探测使用场景 MySQL 中被频繁访问的数据 &#xff0c;如热门商品的主键 IdRedis 缓存中被密集访问的 Key&#xff0c;如热门商品的详情需要 get goods$Id恶意攻击或机器人爬虫的请求信息&#xff0c;如特定标识的 userId、机器 IP频繁被访问的接口地址&#xff0c;如获取用…

MCU_IO驱动LED

注意事项&#xff1a; 1、亮度要求较高的情况下&#xff0c;不能由IO直接驱动LED MCU_IO引脚输出的电压和电流较弱&#xff0c;如果对光的亮度有要求的话&#xff0c;需要使用三极管来驱动。 MCU_IO的电压一般为3.3V或者5V&#xff0c;输出电流一般10mA-25mA。 2、不同颜色…

MyBatis 深度解析:高效 Java 持久层框架实践指南(基于 3.5.10)

一、MyBatis 核心架构与设计哲学 MyBatis 作为半自动 ORM 框架&#xff0c;核心设计目标是在灵活性与开发效率之间取得平衡。与 Hibernate 等全自动 ORM 框架不同&#xff0c;MyBatis 允许开发者完全控制 SQL 编写&#xff0c;同时通过映射机制减少重复代码&#xff0c;特别适…

二叉树(二)

98.验证二叉树 中序遍历二叉树&#xff0c;每次遍历存下当前节点的值&#xff0c;遍历到下一个节点比较&#xff0c;根据二叉搜索树的特性&#xff0c;左<中<右有&#xff1a; 如果当前值小于或等于上一个的值&#xff0c;说明不是二叉搜索树 如果当前值大于上一个节点…

解决Vue3+uni-app导航栏高亮自动同步方案

路由跳转自动识别导航高亮实现方法 以下代码使用wd-tabbar组件实现路由跳转时自动同步导航栏高亮状态&#xff0c;适用于所有的Vue3uni-app项目。 请根据自身使用框架类型完成&#xff0c;也可根据我使用的UI组件进行完成地址如下&#xff1a; Tabbar 标签栏 | Wot UI &#…

免费论文查重与AI检测工具推荐

文章目录 概要一、PaperPass二、PaperYY注意 概要 毕业季&#xff0c;总少不了查重这一步&#xff0c;甚至查 AI 率。推荐两款免费查重AIGC检测的工具。 论文免费查重查AI&#xff1a; https://paperpass.com/ https://www.paperyy.com/ 一、PaperPass 网址&#xff1a; ht…

4、ubuntu系统 | 文本和目录操作函数

1、目录操作函数 ls(列出目录内容) 用途:列出指定目录中的文件和子目录。语法:ls [选项] [路径]常用选项: -l:以长格式显示文件详细信息(权限、所有者、大小、时间等)。-a:显示隐藏文件(以.开头的文件)。-R:递归列出子目录内容。# 列出当前目录下的所有文件和子目…

C++--范围for循环详解

范围 for 循环是 C11 引入的语法特性&#xff0c;用于简化遍历容器或数组元素的过程。它比传统 for 循环更简洁安全&#xff0c;特别适合初学者。以下是详细讲解&#xff1a; 基本语法 for (元素类型 变量名 : 容器/数组) {// 循环体&#xff08;使用变量名访问当前元素&#…

RDMA简介1之RDMA开发必要性

为了满足大批量数据的采集、存储与传输需求&#xff0c;越来越多的数据密集型应用如机器学习、雷达、金融风控、航空航天等选择使用现场可编程逻辑门阵列作为数据采集前端硬件来实现高性能的数据采集系统。FPGA凭借其高灵活性、高并行能力及可高度定制化的特点&#xff0c;能够…

xmake的简易学习

文章目录 1. xmake是什么2. 一个可执行程序3. 一个库文件4. 遍历文件用法5. 第三方库3.1 系统安装库3.2 独立库 6. 后续 由于前一篇博客的最后说要做一些rknn的优化&#xff0c;其实这个工作很早就完成了&#xff0c;但是我是使用 xmake这个来做我的工程的构建的&#xff0c;不…

【ArcGIS微课1000例】0147:Geographic Imager6.2下载安装教程

文章目录 一、软件功能二、下载地址三、安装教程Geographic Imager地图工具使Adobe Photoshop空间图像可以快速高效地工作。它增加了导入,编辑,操作和导出地理空间图像的工具,例如航空和卫星图像。Geographic Imager Mac功能非常强大,拥有栅格数据输出、投影信息修改、基于…

【 java 集合知识 第一篇 】

1.概念 1.1.集合与数组的区别 集合&#xff1a;长度不固定&#xff0c;动态的根据数据添加删除改变长度&#xff0c;并且只能存入引用类型&#xff0c;读取采用迭代器或其他方法 数组&#xff1a;长度固定&#xff0c;不可改变&#xff0c;既可以存入基本类型也可以存入引用…

嵌入式开发学习日志(linux系统编程--系统编程之 进程间通信IPC)Day32

一、引言 空间独立&#xff0c;需要一些操作&#xff1b; 分为三大类&#xff1a; 1、古老的通信方式 无名管道 有名管道 信号 2、IPC对象通信 system v BSD suse fedora kernel.org 消息队列(用的相对少&#xff0c;这里不讨论) …

metersphere不同域名的参数在链路测试中如何传递?

域名1&#xff1a;https://api.domain1.com 域名2&#xff1a;https://api.domain2.com 域名1的返回参数stteid会作为域名2的入参 步骤&#xff1a; 1&#xff09;先在metersphere—接口测试—接口定义中创建域名1和域名2的接口 2&#xff09;接口创建好后&#xff0c;在接口测…