接上一节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)<Dfn(v) 则说明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能连接到的已访问的点

下面贴代码

 void tarjan(int now)
{
int tot=;
low[now]=dfn[now]=++k;
for(int i=h[now];i;i=e[i].nex)
{
if(!dfn[e[i].to])
tarjan(e[i].to),low[now]=min(low[now],low[e[i].to]),++tot;
else
low[now]=min(low[now],dfn[e[i].to]);//更新Low
if(now==root&&tot>||now!=root&&low[e[i].to]>=dfn[now])
flag[now]=;//割点的判断
}
}

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

代码类似求割点

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

事实上在求割点的同时可以顺便求出点双连通分量 维护一个栈在求割点的途中若Low(u)<Dfn(v)则 将(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条)

Tarjan算法初探(3):求割点与桥以及双连通分量的更多相关文章

  1. tarjan算法--求解无向图的割点和桥

    1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥 也就是说 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥 2.割点:无向连通图中,如 ...

  2. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

  3. Tarjan算法初探(2):缩点

    接上一节 Tarjan算法初探(1):Tarjan如何求有向图的强连通分量 Tarjan算法一个非常重要的应用就是 在一张题目性质在点上性质能够合并的普通有向图中将整个强连通分量视作一个点来把整张图变 ...

  4. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  5. DFS的运用(二分图判定、无向图的割顶和桥,双连通分量,有向图的强连通分量)

    一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISI ...

  6. Tarjan求割点和桥

    by szTom 前置知识 邻接表存储及遍历图 tarjan求强连通分量 割点 割点的定义 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多, ...

  7. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  8. 图论之tarjan真乃神人也,强连通分量,割点,桥,双连通他都会

    先来%一下Robert Tarjan前辈 %%%%%%%%%%%%%%%%%% 然后是热情感谢下列并不止这些大佬的博客: 图连通性(一):Tarjan算法求解有向图强连通分量 图连通性(二):Tarj ...

  9. 割点和桥---Tarjan算法

    使用Tarjan算法求解图的割点和桥. 1.割点 主要的算法结构就是DFS,一个点是割点,当且仅当以下两种情况:         (1)该节点是根节点,且有两棵以上的子树;         (2)该节 ...

随机推荐

  1. 公司网络问题 & Caused by: org.gradle.internal.resource.transport.http.HttpRequestException

    问题 公司网络问题,总是无法成功下载库,回到家就可以. Caused by: org.gradle.internal.resource.transport.http.HttpRequestExcept ...

  2. qt 拖放dropEvent

    1.拖放操作分为两个截然不同的动作: 拖动和放下. 拖动通过 void dragEnterEvent(QDragEnterEvent * event); 来实现. 放下通过 void dropEven ...

  3. 爬虫day02

    s10day112 内容回顾: 第一部分:爬虫相关 1. 谈谈你对http协议的理解? 规范: 1. Http请求收发数据的格式 GET /index/ http1.1/r/nhost:xxx.com ...

  4. HTML 的 style 属性

    style 属性用于改变 HTML 元素的样式. This text is in Verdana and red This text is in Times and blue This text is ...

  5. Django中请求的生命周期 和 FBV模式和CBV模式

    Django的生命周期就是你的 一个请求所发生的整个流程 Django的生命周期内到底发生了什么呢?? . 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏 ...

  6. bmp制作自定义字体(cocostudio使用)

    工具需求:bmpfont 1.步骤 (1)制作 * 把自己的字体放到一个txt文件中,写个脚本抽离出来, 重复了没有关系 * Edit->Select chars from fils(注意:Ed ...

  7. linux的pthread_self与gettid的返回值和开销的区别

    linux的pthread_self与gettid的返回值和开销的区别 linux的pthread_self与gettid的返回值和开销的区别 分类: 一些思考 2012-05-18 12:25 17 ...

  8. 串口编程 System.IO.Ports.SerialPort类

    从Microsoft .Net 2.0版本以后,就默认提供了System.IO.Ports.SerialPort类,用户可以非常简单地编写少量代码就完成串口的信息收发程序.本文将介绍如何在PC端用C# ...

  9. Mac下的mongodb安装

    mac下的mongodb安装主要有两种方式,一是手工安装,需在官网下载源文件,二是通过homebrew,至于homebrew不做介绍.既然是Mac系统下,我认为直接通过homebrew安装最好,省事还 ...

  10. CCControlExtension/CCControl

    #ifndef __CCCONTROL_H__ #define __CCCONTROL_H__ #include "CCInvocation.h" #include "C ...