题外话:
今天不想码代码了,知识普及的一天

注意:以下内容是在无向图的基础上

无向图的割点

很久之前就知道这些名词
今天终于可以来填坑了。。。

如果将连通图G中的某个点及和这个点相关的边删除后,将使连通分量数量增加,那么这个点就称为图G的割点或是接合点。
如果一个无向图没有割点,则这样的图被称为双连通图。
关于图的割点,有如下两条性质:

【性质一】
如果深度优先搜索树的根节点至少有两个以上的子节点,则根节点是割点。显然去掉根节点后将得到以子节点为根结点的森林。

【性质二】
在深度优先搜索树中,v存在一个子节点不能通过后向边到达v的祖先节点,则节点v是割点。
也就是说从v的子节点开始没有一条边能够回到v的祖先节点,那么当去掉v时将会使得v的子孙节点与v的祖先节点之间失去联系。必定会使得图不再连通。

可以通过对图的深度优先搜索,
加上上面的两条性质来寻找图中的割点。
在对图进行深度优先搜索时,记录下遍历的顺序pre_order
pre_order从小到大就代表了从根节点一直到叶子节点。
在遍历的时候同时得出每一个节点通过自己或是子孙节点的后向边(不是从父亲直接来的边)所能达到的最原始的祖先,
也就是pre_order最小的节点,记录在back_order中。
那么如果一个节点的back_order>=父节点的pre_order
说明该节点的子孙节点不存在一条后向边到达父节点的祖先节点,则根据第二条性质,该节点必是割点。

back_order的计算

由于back_order记录的是节点所能返回到的最原始的祖先节点,
初始化back_order[v]=pre_order[v]
及顶点v所能返回的最原始祖先就是自己。
在对v进行深搜时,如果与v相邻的下一个节点w没被访问过,说明(v,w)是生成树上的边,
那么back_order[v]就应该是v和w中能返回到最原始祖先的点的back_order
back_order[v]=min(back_order[v],back_order[w])
如果w已经被访问过,说明w就是v的祖先,那么back_order[v]就应该是v之前计算得到的所能返回的祖先节点与w之间最小的一个,
back_order[v]=min(back-order[v],pre_order[w])。


int pre[N];
int back[N]; int dfs(int now,int fa)
{int low=pre[now]=++tot;   //时间戳++int ch=0;    //子节点个数 for (int i=st[now];i;i=way[i].nxt){int v=way[i].y;if (!pre[v])   //v是子节点 {ch++;int lowv=dfs(v,now);   //子节点能够回溯到的最远祖先 low=min(low,lowv);if (lowv>=pre[now])   //存在一个子节点与祖先不联通,now就是割点 iscut[now]=1;   //割点 }else if (pre[v]<pre[now]&&v!=fa)   //是祖先,但不是直接父亲 {   //说明low是之前计算得到的所能返回的祖先节点 low=min(low,pre[v]);}}if (fa<0&&ch==1) iscut[now]=0;   //性质一的验证 back[now]=low;return low;
}

注意

一定要写v!=fa
因为边(u,fa)不是反向边,而是dfs树边(fa,u)的第二次遍历
pre的初始化是0,第一次调用时,fa的初始值是-1

附:训练指南(刘汝佳著)P312上有更详尽的解释

无向图的桥

作为一种特殊情况,u为v的父节点,且low(v) < pre(u)
那么我们只要删掉(u,v)这条边就可以让无向图不连通了
满足这个条件的边叫做无向图的桥
也就是说,我们知道了u是割点,而且(u,v)是桥、

int dfs(int now,int fa)
{int ch=0;int low=pre[now]=++tt;for (int i=st[now];i;i=way[i].nxt){int v=way[i].y;if (!pre[v]){int lowv=dfs(v,now);low=min(low,lowv);ch++;if (lowv>pre[now])  //存在即合理 {  //因为只找桥,所以在这里我就省去了割点的记录an++;ans[an].x=min(now,v);ans[an].y=max(now,v); }  }else if (pre[v]<pre[now]&&v!=fa){low=min(low,pre[v]);}}back[now]=low;return low;
}

无向图的双连通分量

对于一个连通图,如果任意两点至少存在两条“点不重复”的路径,则说这个图是点-双连通的(一般简称双连通)
这就相当于任意两条边都在同一个简单环中,即内部无割点

类似的,如果任意两个点至少存在“边不重复”的路径,我们说这个图是边-双连通的。
即所有边都不是桥

对于一张无向图,点-双连通的极大子图称为双连通分量

边-双连通的极大子图称为边双连通分量(BCC)
也就是说,在删除所有的桥之后,每个连通分量对应原图中的一个边-双连通分量

下面给出点双(BCC)的计算方法

int pre[N],iscut[N],bccno[N],tot=0,bcc_cut;
vector bcc[N];
stack<node> S;int dfs(int now,int fa)
{int low=pre[now]=++tot;int ch=0;for (int i=st[now];i;i=way[i].nxt){int v=way[i].y;node e=way[i];if (!pre[v]){S.push(e);ch++;int lowv=dfs(v,now);low=min(low,lowv);if (lowv>=pre[now]){iscut[now]=1;bcc_cnt++;bcc[bcc_cnt].clear;for (;;){node x=S.top();S.pop();if (bccno[x.x]!=bcc_cnt){bcc[bcc_cnt].push_back(x.x);bccno[x.x]=bcc_cnt;}if (bccno[x.y]!=bcc_cnt){bcc[bcc_cnt].push_back(x.y);bccno[x.y]=bcc_cnt;}if (x.x==now&&x.y==v) break;}}else if (pre[v]<pre[now]&&v!=fa){S.push(e);low=min(low,pre[v]);}}}if (fa<0&&ch==1) iscut[now]=0;return low;
}void find_bcc(int n)
{memset(pre,0,sizeof(pre));memset(iscut,0,sizeof(iscut));memset(bccno,0,sizeof(bccno));tot=bcc_cnt=0;for (int i=1;i<=n;i++)   //森林 if (!pre[i])dfs(i,-1);
}

边双的计算方法更简单,分两个步骤,
先作一次dfs标记出所有的桥,然后再做一次dfs找出边双
因为边双不能经过桥而且两个边双之间没有公共点,
所以在dfs的时候只要保证不经过桥即可

转载于:https://www.cnblogs.com/wutongtong3117/p/7673121.html

图上的文章(割点和桥)相关推荐

  1. JOJ2737:狼与羊的故事(求图上任意两点间的桥边)

     2737: 狼与羊的故事 Result TIME Limit MEMORY Limit Run Times AC Times JUDGE 3s 65536K 53 10 Standard 村长要召开 ...

  2. 图的割点、桥与双连通分支

    [点连通度与边连通度] 在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合.一个图的点连通度的定义为,最小割点集 ...

  3. [转载]图的割点、桥与双连通分支

    [点连通度与边连通度] 在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合.一个图的点连通度的定义为,最小割点集 ...

  4. 图的割点、桥和双连通分支的基本概念

    点连通度与边连通度 回到正题,首先介绍下什么是图的边连通度和点连通度.一般来说,点连通度是指对应一个图G,对于所有点集U属于V(G),也就是V(G)的子集中,使得G-U要么是一个非连通图,要么就是一个 ...

  5. 图的割点、桥与双连通分支的基本概念

    [点连通度与边连通度] 在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合.一个图的点连通度的定义为,最小割点集 ...

  6. 001.Tarjan算法:求解图的割点与桥(割边)

    简介: 割边和割点的定义仅限于无向图中.我们可以通过定义以蛮力方式求解出无向图的所有割点和割边,但这样的求解方式效率低.Tarjan提出了一种快速求解的方式,通过一次DFS就求解出图中所有的割点和割边 ...

  7. 图论 —— 图的连通性 —— Tarjan 求割点与桥

    [概念] 1.割点 1)割点:删除某点后,整个图变为不连通的两个部分的点 2)割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 3)点连通度:最小割点集合点数 如上 ...

  8. 第1节 连通性强连通、割点和桥(一)

    文章目录 无向图割点.桥.双连通分量 Tarjan算法求割点和桥(割边) 代码: 边双连通分量 和 点双连通分量 代码 边双连通分量 和 点双连通分量 的缩点 有向图的弱连通与强连通 强连通分量 Ko ...

  9. 模板:割点、桥与双连通

    文章目录 割点 代码 桥 点双连通分量 代码 边双连通分量 代码 割点 和强连通分量十分相似 分为树枝边.前向边和后向边 注意! if(x!=r&&low[to]>=dfn[x] ...

最新文章

  1. docker-2-简单使用docker-ce
  2. Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇
  3. SrpingCloud 之SrpingCloud config分布式配置中心
  4. java动态代理(JDK和cglib)
  5. 支持.NET的分布式缓存系统memcached
  6. 第13届年度Webby奖采用Silverlight / 13th Annual Webby Awards powered by Silverlight
  7. Win10安装 oracle11g 出现INS-13001环境不满足最低要求解决方法
  8. Reusability1
  9. mysql还要mysqldump的备份文件到指定数据库
  10. 微软发布 .Net Core 3.0 版重大更新,对开发者来说意味着什么?
  11. 浏览器管理oracle网址,浏览器用户界面 (Browser User Interface, BUI)
  12. Python入门--while循环
  13. null和空的区别 oracle,Oracle中NULL与空字符串''的区别的总结
  14. 计算机监控网络运维合同书,网络服务托管运维合同范本
  15. C语言程序设计基础笔记
  16. 国际云安全证书CCSK让他们在职场中脱颖而出
  17. NVIDIA Jetson TX2 更新软件源
  18. 2023计算机毕业设计SSM最新选题之java亚健康人群健康管理系统c4cyz
  19. 如何优化SEO的网站结构
  20. word隐藏段落标记,回车三角

热门文章

  1. 如何配置天融信NGFW4000防火墙基于长连接的访问策略
  2. linux问答学知识
  3. html标签的嵌套规则
  4. 出现次数超过一半的数字
  5. 图结构练习——BFS——从起始点到目标点的最短步数
  6. Python 并发编程之使用多线程和多处理器
  7. go web本地化资源
  8. golang已关闭channel
  9. strace命令学习
  10. 理想的教育是从父母自我改变开始