学习笔记--Tarjan算法之割点与桥
前言
图论中联通性相关问题往往会牵扯到无向图的割点与桥或是下一篇博客会讲的强连通分量,强有力的\(Tarjan\)算法能在\(O(n)\)的时间找到割点与桥
定义
若您是第一次了解\(Tarjan\)算法,建议您反复阅读定义,借助图像来理解
- 桥与割边
对于无向连通图中点集的一个节点\(x\),删去节点\(x\)及其关联的边之后,存在一对不联通的点对\((a,b)\),则称\(x\)是这个无向图的割点
对于无向联通图中边集的一条边\(e\),删去边\(e\)之后,存在一对不联通的点对\((a,b)\),则称\(x\)是这个无向图的桥或割边
对于一般无向图,割点和桥可以指各个联通块的割点和桥
- 时间戳:
在对图的\(DFS\)中,按照节点第一次被访问的顺序,给各个节点标记一个值,该值称为时间戳,我们用\(dfn[x]\)表示\(x\)的时间戳
- 搜索树
在对图的\(DFS\)中,由于每个点只会被搜一次,所以访问经过的边构成了一棵树,称为搜索树,各个节点为根的子树称为\(subtree(x)\),注意,\(x \in subtree(x)\)
- 追溯值
这个可以说是\(Tarjan\)算法的精髓了,在我个人看来,节点\(x\)的追溯值是指不经搜索树所能到达的所有节点中其时间戳的最小值或者它自身的时间戳.
这看起来很难得到各个节点的追溯值,实则不然,分析一下,节点\(x\)的追溯值可以在一遍\(DFS\)中求得,请看下文介绍
算法
性质一: 桥边都是搜索树上的边
反证法,若桥边不是搜索树上的边,断掉这条之后仍可通过搜索树上的边保持图的联通
割边判定法则
无向边\((x,y)\)是桥的充要条件是\(dfn[x]<low[y]\)(假设\(y \in subtree(x)\))
让我们想想为什么
\(low[y]\)表示不经搜索树上的边\(y\)所能到达的所有节点中其时间戳的最小值,若\(dfn[x]<low[y]\),根据定义和性质一,说明只有这条在s搜索树上的边\((x,y)\) ,\(y\)才能到达\(x\),故边\((x,y)\)是桥(割边)
割点判定法则
非根点\(x\)是割点的充要条件是存在一点\(y (y \in subtree(x))\),满足\(dfn[x]<=low[y]\),类比于上一法则,这里不再赘述
当\(x\)为根节点时至少要有两个点满足上述条件
注意
更新\(low[x]\)
根据定义,我们只能用\(x\)在搜索树上儿子的\(low[]\)值或是一条非搜索树边\((x,y)\)中的\(dfn[y]\)来更新\(low[x]\)
重边
在求桥时,若节点\(x\)与其父亲间有重边,则其中只有一条算搜索树上的边,其他都是非搜索树上的边,可以用来更新.
然而求割点时,由于是点与点联通关系不必考虑重边
代码
- 桥
int dfn[maxn],low[maxn],cnt=0;
bool bridge[maxm];
void tarjan(int u,int in_edge){//in_edge--边的编号
int v;dfn[u]=low[u]=++cnt;
for(ri i=h[u];i;i=edge[i].ne){
v=edge[i].to;
if(!dfn[v]){
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
bridge[i]=bridge[i^1]=1;
}
}
else if(i!=(in_edge^1)){
//in_edge^1表示反向边,不是反向边说明是非搜索树边
low[u]=min(low[u],dfn[v]);//通过非树边更新
}
}
return ;
}
- 缩点
int dfn[maxn],low[maxn],root,tot=0;
bool ans[maxn];
void tarjan(int now){
int v,flag=0;dfn[now]=low[now]=++tot;
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[now]=min(low[now],low[v]);
if(dfn[now]<=low[v]){
flag++;
if(now!=root||flag>1)//根节点要有两个满足条件
{
if(!ans[now])ans[now]=1;//是割点
}
}
}
else low[now]=min(low[now],dfn[v]);
}
return ;
}
例题
桥+缩点
https://www.luogu.org/problemnew/show/P2860
题解:
https://rye-catcher.github.io/2018/07/09/luogu题解P2860-USACO冗杂路径-缩点-桥/
[模板]割点
割点+简单计数
https://www.luogu.org/problemnew/show/P3469
题解:咕咕咕
学习笔记--Tarjan算法之割点与桥的更多相关文章
- [学习笔记] Tarjan算法求桥和割点
在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...
- [学习笔记] Tarjan算法求强连通分量
今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...
- Tarjan的学习笔记 求割边求割点
博主图论比较弱,搜了模版也不会用... 所以决心学习下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结 ...
- Tarjan无向图的割点和桥(割边)全网详解&算法笔记&通俗易懂
更好的阅读体验&惊喜&原文链接 感谢@yxc的腿部挂件 大佬,指出本文不够严谨的地方,万分感谢! Tarjan无向图的割点和桥(割边) 导言 在掌握这个算法前,咱们有几个先决条件. [ ...
- [ML学习笔记] XGBoost算法
[ML学习笔记] XGBoost算法 回归树 决策树可用于分类和回归,分类的结果是离散值(类别),回归的结果是连续值(数值),但本质都是特征(feature)到结果/标签(label)之间的映射. 这 ...
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
- Tarjan算法求割点
(声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...
- [Tarjan系列] Tarjan算法求无向图的桥和割点
RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...
- tarjan算法应用 割点 桥 双连通分量
tarjan算法的应用. 还需多练习--.遇上题目还是容易傻住 对于tarjan算法中使用到的Dfn和Low数组. low[u]:=min(low[u],dfn[v])--(u,v)为后向边,v不是u ...
随机推荐
- 搭建Django项目虚拟环境(Windows系统下)
一.安装virtualenv 我们可以使用正式的Python环境中的pip进行安装.进入cmd界面,运行“ pip install virtualenv ”,完成安装后,可以运行“ where vir ...
- 可插拔式后台管理系统(Django)
1.实现效果 研究了下django admin的功能,自己实现了一个简单的可插拔式后台管理系统,方便自定义特殊的功能,而且作为一个独立单独的django app,可以整体拷贝到其他项目中作为后台数据管 ...
- react-native-swiper设定高度的方法(设置rn轮播图所占高度)
效果图: 直接上解决方案: 1.在Swiper标签外套一层View <View style={styles.container}> <Swiper style={styles.wra ...
- [Java复习] 多线程 Multithreading
Q1多线程基础 进程和线程? 进程: 1. 一段程序执行过程,动态的,相对而言程序是静态的.(与类和对象的关系类似) 2. CPU资源分配最小单元,包括CPU调度和资源管理. 3. 一个进程可以有多个 ...
- linux 自动输入用户名和密码 ftp
参考文章: http://blog.sina.com.cn/s/blog_8709e3120101culd.html 方法概括; 1.echo管道 2. 利用重定向操作符command <&l ...
- docker 搭建私有云盘 Seafile
缘起 现如今各种云存储服务其实挺多的,国外有经典的DropBox.Google Drive.微软的OneDrive等,国内也有可以免费使用的各种云. 那么为什么想要搭建私有云存储呢?主要是本着“自己的 ...
- mysql安装报错error: Header V3 DSA signature: BAD, key ID
CentOS安装rpm安装MySQL时爆出警告: warning: mysql-community-server-5.7.18-1.el6.x86_64.rpm: Header V3 DSA/SHA1 ...
- 拷贝docker镜像到其他机器部署
有拷贝docker images到其他主机的情况,当然是通过pull的方式来转移到其他宿主机. 1 sudo docker save -o golang:alpine3.7 ./my-golang- ...
- Protel99SE推荐使用英文版
Protel99SE的汉化版功能并不全,最好还是用英文原版,功能是最齐全的.用英文版的软件其实也不难,有限的几个词,习惯就好了.
- 动态加载js不执行解决办法
这个问题的产生原因是:我们项目有一个主index文件,在主index文件中需要根据参数来判断是加载pc.html的内容还是加载mobile.html的内容,一开始是使用jquery来做的,没有问题,后 ...