热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Tarjan算法初探(3):求割点与桥以及双连通分量

接上一节Tarjan算法初探(2):缩点在此首先提出几个概念:割点集合:一个无向连通图G若删除它的一个点集以及点集中所有点相连的边(任意一端在点集中)后

 

接上一节Tarjan算法初探(2):缩点

 

在此首先提出几个概念:

割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的一个割点集合

割边集合:一个无向连通图G 若删除它的一个边集 G中有点之间不再连通则称这个边集是它的一个割边集合

图的点联通度:无向连通图的最小割点集合中元素的个数是一张无向连通图的点连通度

图的边联通度:无向连通图的最小割边集合中元素的个数是一张无向连通图的边联通度

割点:如果一个无向连通图的点连通度为1 那么割点集合中唯一的点就是割点

:如果一个无向连通图的边连通度为1 那么割边集合中唯一的边就是桥

点双连通(或复连通):无向连通图的点连通度大于1

边双连通(或复连通):无向连通图的边连通度大于1

点双连通子图:G'是点双连通的 G'是G的子图 则G'是G的一个点双连通子图

点双连通分量:G'是G的一个点双连通子图 同时G'不是G的点双连通子图的真子集 那么G'就是一个极大点双连通子图 G'也是G的点双连通分量 点双连通分量又叫

边双连通子图:G'是边双连通的 G'是G的子图 则G'是G的一个边双连通子图

边双连通分量:G'是G的一个边双连通子图 同时G'不是G的边双连通子图的真子集 那么G'就是一个极大边双连通子图 G'也是G的边双连通分量

 

概念有点多 但都很简单 希望仔细看完

 

下面讲割点与桥的求法:

割点的定义可知若在dfs搜索树中无向图的一个节点V是割点 当且仅当满足下面两个条件中任意一个时成立:

1.V是根节点 则当它的子树个数多于1时 若子树个数小于等于1 则V此时不在两点间的路径上 V只能是一条路径的起点和终点 删除V不影响剩下的点之间的连通性

2.V不是根节点 且Low(u)>=Dfn(v),u∈v的子节点 Low(u)表示u及u的子树能够访问到的最早的点的dfs序 而Dfn(u)表示u的dfs序 由于无向图不存在两颗子树之间的连边 故Low(u) 则说明u能够走不过v点的路径访问到v的父亲或祖父节点 故当Low(u)>=Dfn(v)时v是u向上走的唯一路径中的一个点 故删除v会破坏图的连通性 删除v后u与v的父亲或祖父节点不再连通

代码具体实现:

类似Tarjan求强连通分量 由于是无向图 故不需要判断一个点连接到已访问的点是不是在栈中(因为在无向图中一个点连接到已访问的点时这两个点必在同一棵子树内)且重边不影响割点的判断

同时

Low[u]=min(Low[u],Low[v]),v∈u的子节点

Low[u]=min(Low[u],dfn[v]),v∈u能连接到的已访问的点

下面贴代码

 

1 void tarjan(int now)
2 {
3 int tot=0;
4 low[now]=dfn[now]=++k;
5 for(int i=h[now];i;i=e[i].nex)
6 {
7 if(!dfn[e[i].to])
8 tarjan(e[i].to),low[now]=min(low[now],low[e[i].to]),++tot;
9 else
10 low[now]=min(low[now],dfn[e[i].to]);//更新Low
11 if(now==root&&tot>1||now!=root&&low[e[i].to]>=dfn[now])
12 flag[now]=1;//割点的判断
13 }
14 }

 

在无向图中判断一条边(u,v)是 当且仅当(u,v)是搜索树上的一条边 且Low(u)>Dfn(v) 时成立 在这时(u,v)是u到v唯一路径 故删除(u,v) u,v不连通 此时重边会影响桥的判断 所以我们把一条无向边拆成编号相邻的边那么在实际操作中我们就可以判断一条边是重边还是原来边的反向边 反向边不能继续访问了 因为在Low(u)>Dfn(v)时判断割边 若走反向边会影响判断

代码类似求割点

再说下点双连通分量的求法 :

事实上在求割点的同时可以顺便求出点双连通分量 维护一个栈在求割点的途中若Low(u)则 将(u,v)入栈 而当Low(u)>=Dfn(v)时将栈中所有在(u,v)之上的边全部取出,这些边所连接的点与u点构成了一个点双连通分量 而显然割点是可以属于多个点双连通分量的

代码不贴了

 

边双连通分量的求法更为简单

将求得的割边全部删除 剩下的所有连通块都是边连通分量 同时边连通分量不一定是点连通分量 但点连通分量一定是边连通分量除了下图所示的情况以外

删去 边(1,2) 图不再连通

 

 

 

 

对于有割边的无向连通图来说 更重要的是如何把通过加边使它的边连通度不再为1 这个问题相较于点连通分量来说更为复杂 故单独提出来分析一下:

首先将所有删掉桥后的连通块视作一个点 再把桥边加回来得到的必定是一棵树 统计其中度为1的叶子点数为leaf 则最少需要添加(leaf+1)/2条边(leaf==1时为0条)

若加的边满足如下情况(连接的两点之间有两条支链)则会使叶子节点减少1 否则不会使叶子节点数减少 (三个叶子需要两次)

连接1 5后重缩点 会使叶子节点减少1

 

而我们的目标是使叶子节点数为1,而每次操作会使叶子节点数减少1 减少到3时特判即可 最终得到规律:最少要(leaf+1)/2条边(leaf==1时为0条)

转:https://www.cnblogs.com/dah1314/p/10698853.html



推荐阅读
  • pypy 真的能让 Python 比 C 还快么?
    作者:肖恩顿来源:游戏不存在最近“pypy为什么能让python比c还快”刷屏了,原文讲的内容偏理论,干货比较少。我们可以再深入一点点,了解pypy的真相。正式开始之前,多唠叨两句 ... [详细]
  • 现在越来越多的人使用IntelliJIDEA,你是否想要一个好看的IDEA主题呢?本篇博客教你如何设置一个美美哒IDEA主题,你也可以根据 ... [详细]
  • 本题要求实现一个高效的算法,在一个 m x n 的矩阵中搜索目标值 target。该矩阵具有以下特性:每行的元素从左到右按升序排列,每列的元素从上到下按升序排列。 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • c#  项目文件,C#viual studio使用方法
    一、项目文件1)Properties节点下主要存放的是当前程序集相关的信息,如版本号、标题等。双击”Properties“,打开如下项目属 ... [详细]
  • 本文详细介绍了如何在Android应用中实现重复报警功能。示例代码可在以下路径找到:https://developer.android.com/samples/RepeatingAlarm/index.html。首先,我们将从Manifest文件开始分析。 ... [详细]
  • 本文详细介绍了Sleep函数的基本概念、使用方法及其背后的实现原理。适合对Sleep函数的使用和实现感兴趣的开发者阅读。通过本文,您将了解如何在不同操作系统中使用Sleep函数,以及其在多线程编程中的重要性。 ... [详细]
  • LeetCode 125: 验证回文字符串 (Valid Palindrome)
    本题要求检查给定的字符串是否为回文。在判断过程中,仅考虑字母和数字字符,并且忽略大小写。例如,"A man, a plan, a canal: Panama" 是一个回文。 ... [详细]
  • 本文详细介绍了 Python 中的快速排序算法,包括其原理、实现方法以及应用场景。同时,还探讨了其他常见排序算法及其特点。 ... [详细]
  • 列表生成式虽然简洁高效,但在处理复杂算法时存在局限性。本文将介绍生成器(generator)的概念及其优势,探讨如何通过生成器解决列表生成式的局限性,并提供实际示例。 ... [详细]
  • php三角形面积,335宝石大全
    php三角形面积,335宝石大全 ... [详细]
  • 尽管Medium是一个优秀的发布平台,但在其之外拥有自己的博客仍然非常重要。这不仅提供了另一个与读者互动的渠道,还能确保您的内容安全。本文将介绍如何使用Bash脚本将Medium文章迁移到个人博客。 ... [详细]
  • CentOS7通过RealVNC实现多人使用服务器桌面
    背景:公司研发团队通过VNC登录到CentOS服务器的桌面实现软件开发工作为防止数据外泄,需要在RealVNC设置禁止传输文件、访问粘贴板等策略过程&# ... [详细]
  • 在开发板的启动选项中看到如下两行:7:LoadBootLoadercodethenwritetoFlashviaSerial.9:LoadBootLoadercodethenwri ... [详细]
author-avatar
ningxiao088_272
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有