连通性2 无向图的割边 (cut edge)
这是DFS系列的第二篇
In graph theory, a bridge, isthmus, cut-edge, or cut arc is an edge of a graph whose deletion increases its number of connected components. Equivalently, an edge is a bridge if and only if it is not contained in any cycle. A graph is said to be bridgeless or isthmus-free if it contains no bridges.
Let $G = (V, E)$ be a connected, undirected graph, a bridge of $G$ is an edge whose removal disconnects $G$. (Introduction to Algorithms p.621)
注意:割边这一概念只适用于无向图,不适用于有向图,因为有向图的连通性和无向图的连通性是完全不同的两个概念。对于某有向图 $G$,简单地称它连通是很不完善的。有向图的连通性有强连通(strongly connected)和半连通(semiconnected)两种常见的提法。上面英文描述中的“graph”及下文中的“图”均指无向图。
割边 (cut edge)也称作桥(bridge)是删除后能使图的连通分量增加的边。
下面我们只考虑没有重边的无向图。
考虑一个连通的无向图 $G$,若它含有某条割边 $(u, v)$,那么去掉这条边后,将得到2个连通图 $G'$,$H'$,而不可能得到 $2$ 个以上连通图,因为一条边最多能将 $2$ 个连通图合为一个联通图。(这句话貌似和上下文无关)
下面介绍求无向图所有割边的Tarjan算法(Tarjan's Bridge-Finding Algorithm)
我们只考虑对无向连通图 $G$ 求割边,若图 $G$ 不连通那么就对 $G$ 的各个连通分量求割边。
我们知道 DFS 一个无向图将其所有边分成两类,树边(tree edge)与回边(back edge)。显然地,割边只能是树边而绝不可能是回边。
考虑 一条树边 $(u\to v)$ 是割边 的条件。这条件应当是在DFS树中,以 $v$ 为根的子树(简称子树 $v$)中的所有节点都没有连向 $u$ 的祖先节点(包括 $u$ 本身)的回边,也就是说子树 $v$ 仅仅靠着边 $(u,v)$ 和其他节点保持连通。
为了判断上述条件,我们在 DFS 过程中记录每个节点的 dfn 值与 low 值,树边 $(u\to v)$ 是割边的充要条件即是 \(\color{blue}{\mathrm{low}[v]>\mathrm{dfn}[u]}\) 。
struct edge{
int to, nt;
bool flag;
}E[MAX_E<<];
int head[MAX_V];
int dfn[MAX_V], low[MAX_V];
int ts; //time stamp
void dfs(int u, int f){
dfs[u]=low[u]=++ts;
for(int i=head[i]; ~i; i=E[i].nt){
int &v=E[i].to;
if(!dfn[v]){ //tree edge
dfs(v, f);
low[u]=min(low[u], low[v]);
if(low[v]>dfn[u]){
e[i].flag=e[i^].flag=true;
}
}
else if(v!=f&&dfn[v]<dfn[u]){ //back edge
low[u]=min(low[u], dfn[v]);
}
}
}
void solve(int N){
memset(dfn, , sizeof(dfn));
ts=;
for(int i=; i<=N; i++)
if(!dfn[i]) dfs(i, i);
}
现在考虑有重边的情况。这时上面的写法不能识别所有回边。首先明确一点:不论是否有重边,DFS 都将所有边分成树边与回边两类。
但是按上面的写法,所有重边要么全是树边,要么全是回边,因而不能识别所有回边(这并不是 DFS 算法本身有问题,而是写法有问题)。这是因为 DFS 的参数是 $u$(当前节点)和 $f$(当前节点的父亲节点),我们判断回边的依据是
else if(v!=f&&dfn[v]<dfn[u]){ //back edge
low[u]=min(low[u], dfn[v]);
}
解决办法是将参数 $u$换成树边 $( u\to f )$ 的编号。
struct edge{
int to, nt, id;
bool tag;
}E[MAX_N<<];
int head[MAX_N];
int dfn[MAX_N], low[MAX_N], ts; //time_stamp
void dfs(int u, int te){
dfn[u]=low[u]=++ts;
for(int i=head[u]; ~i; i=E[i].nt){
int &v=E[i].to, &id=E[i].id;
if(!dfn[v]){ //tree_edge
dfs(v, id);
low[u]=min(low[u], low[v]);
if(low[v]>dfn[u])
e[i].tag=true;
}
else if(id!=te&&dfn[v]<dfn[u]){ //back_edge
low[u]=min(low[u], dfn[v]);
}
}
}
一般来说,没必要在结构体 edge 内加个变量 id,按通常的建图方式,无向边的 ID 就是其对应的某条有向边的 ID 右移一位。
连通性2 无向图的割边 (cut edge)的更多相关文章
- ZOJ2588 Burning Bridges 无向图的割边
题目大意:求无向图的割边编号. 割边定义:在一个连通图中,如果删去一个边e,图便变成不连通的两个部分,则e为该图的割边. 求法:边(u,v) 不是割边,当且仅当边(u,v)在一个环内.因此所有不在环内 ...
- 图连通性【tarjan点双连通分量、边双联通分量】【无向图】
根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- [HDOJ4738]Caocao's Bridges(双联通分量,割边,tarjan)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 给一张无向图,每一条边都有权值.找一条割边,使得删掉这条边双连通分量数量增加,求权值最小那条. ...
- Tarjan 强连通分量 及 双联通分量(求割点,割边)
Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1) 有向图的强联通分量 (2) 无向图的双联通分量(求割点,桥) ...
- LCT(link cut tree) 动态树
模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...
- Tarjan 算法求割点、 割边、 强联通分量
Tarjan算法是一个基于dfs的搜索算法, 可以在O(N+M)的复杂度内求出图的割点.割边和强联通分量等信息. https://www.cnblogs.com/shadowland/p/587225 ...
- UVA796- Critical Links(无向图中的桥梁)
题目链接 题意: 给出一个无向图,按顺序输出桥 思路:求出全部的桥,然后按顺序输出就可以 代码: #include <iostream> #include <cstdio> # ...
- UVA315- Network(无向图割点)
题目链接 题意: 给出一张无向图,求割点的个数 思路:非常裸的题目.直接套用模版就可以. 代码: #include <iostream> #include <cstdio> # ...
随机推荐
- PHP mcrypt加密扩展使用总结
在开发中,很多时候我们在前后端交互中需要对一些敏感数据进行一定的加密.PHP中有提供了mcrypt的这样一个加密扩展实现对数据的加密解密. 一.mcrypt扩展的安装 在低版本的PHP中需要在配置文件 ...
- 千份位Javascript Thousand Separator / string format
function Separator(str){ return str.split(/(\d+)(\d{3})(\d{3})(\d{3})(\d{3})/).join(',').replace(/^, ...
- MySQL初始化简单优化
1,yum 2,源码 3,二进制 4,源码+yum 不管哪种方式装完成数据库,都需要对数据库做一些优化. 优化数据库 mysql> select host,user from mysql.us ...
- [转]World Wind学习总结一
WW的纹理,DEM数据,及LOD模型 以earth为例 1. 地形数据: 默认浏览器纹理数据存放在/Cache/Earth/Images/NASA Landsat Imagery/NLT Landsa ...
- String类及常用方法
在学习String类之前,先看一道笔试题:new String("abc")创建了几个对象? 答案: 两个对象, 一个对象是 位于字符串常量池中,一个对象是位于堆内存中. 原因:主 ...
- python下RSA 加密/解密,签名/验证
基于win7 + python3.4 原文是py2环境,而我的环境是py3,所以对原代码做了修改:decode(), encode() import rsa # 生成密钥 (pubkey, privk ...
- [CareerCup] 12.6 Test an ATM 测试一个自动取款机
12.6 How would you test an ATM in a distributed banking system? 这道题问我们如何来测试一个自动取款机,我们首先要询问下列问题: - 谁来 ...
- Angular JS 学习笔记(自定义服务:factory,Promise 模式异步请求查询:$http,过滤器用法filter,指令:directive)
刚学没多久,作了一个小项目APP,微信企业号开发与微信服务号的开发,使用的是AngularJS开发,目前项目1.0版本已经完结,但是项目纯粹为了赶工,并没有发挥AngularJS的最大作用,这几天项目 ...
- ios上uiwebview的一些实用技巧
前几个星期接到公司一个项目,要用webview在客户端上播视频,作为一个前端实习生,这种需求真是蛋疼……一不知webview是何方神圣,二不知咋调试…… 下面就是蛋疼的开始: 寻找调试工具:好,非w ...
- 简述WebService的使用(二)
上集回顾 上一篇我简单的介绍了一下整个WebService建立和后端访问的过程,如果感兴趣可以看一看:简述WebService的使用(一) //如有不懂请留言,觉得有用请点赞 内容提要 这一篇主要介绍 ...