前言

图论中联通性相关问题往往会牵扯到无向图的割点与桥或是下一篇博客会讲的强连通分量,强有力的\(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\)为根节点时至少要有两个点满足上述条件

注意

  1. 更新\(low[x]\)

    根据定义,我们只能用\(x\)在搜索树上儿子的\(low[]\)值或是一条非搜索树边\((x,y)\)中的\(dfn[y]\)来更新\(low[x]\)

  2. 重边

    在求桥时,若节点\(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 ;
}

例题

学习笔记--Tarjan算法之割点与桥的更多相关文章

  1. [学习笔记] Tarjan算法求桥和割点

    在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...

  2. [学习笔记] Tarjan算法求强连通分量

    今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...

  3. Tarjan的学习笔记 求割边求割点

    博主图论比较弱,搜了模版也不会用... 所以决心学习下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结 ...

  4. Tarjan无向图的割点和桥(割边)全网详解&算法笔记&通俗易懂

    更好的阅读体验&惊喜&原文链接 感谢@yxc的腿部挂件 大佬,指出本文不够严谨的地方,万分感谢! Tarjan无向图的割点和桥(割边) 导言 在掌握这个算法前,咱们有几个先决条件. [ ...

  5. [ML学习笔记] XGBoost算法

    [ML学习笔记] XGBoost算法 回归树 决策树可用于分类和回归,分类的结果是离散值(类别),回归的结果是连续值(数值),但本质都是特征(feature)到结果/标签(label)之间的映射. 这 ...

  6. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  7. Tarjan算法求割点

    (声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...

  8. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

  9. tarjan算法应用 割点 桥 双连通分量

    tarjan算法的应用. 还需多练习--.遇上题目还是容易傻住 对于tarjan算法中使用到的Dfn和Low数组. low[u]:=min(low[u],dfn[v])--(u,v)为后向边,v不是u ...

随机推荐

  1. ReSharper “Cannot resolve symbol” even when project builds

    ReSharper “Cannot resolve symbol” even when project builds   This worked for me (VS2012u4, R# 7.1.3) ...

  2. sql_monitor实时监控

    1 检查数据库是否启用了监控功能 1)检查参数:CONTROL_MANAGEMENT_PACK_ACCES SQL> show parameter CONTROL_MANAGEMENT_PACK ...

  3. [JDBC]批量提交插入语句以提高数据插入速度(效率提升不明显)

    // Initialize conn&stmt Connection conn=null; Statement stmt=null; ... conn=dataSource.getConnec ...

  4. 解决ssh连接超时(ssh timeout)的方法

    echo export TMOUT=1000000 >> /root/.bash_profile (可设置为-1为永不超时) cat /root/.bash_profile source ...

  5. Tween(补间)动画

    视图动画,也叫Tween(补间)动画可以在一个视图容器内执行一系列简单变换(位置.大小.旋转.透明度).譬如,如果你有一个TextView对象,您可以移动.旋转.缩放.透明度设置其文本,当然,如果它有 ...

  6. 003-tomcat配置文件-server、tomcat-users

    1.server.xml讲解 位于conf下 <?xml version="1.0" encoding="UTF-8"?> <!-- Serv ...

  7. linux硬件驱动

    今天被问到了一个新问题:linux需不需要安装驱动,就像windows装完系统之后需要安装最新驱动一样? 说实话以前真没想过,都是装完系统update一下就直接用了. 谷歌了一下,发现其实也是需要安装 ...

  8. SpringBoot: 8.整合freemarker(转)

    1.创建maven项目,添加pom依赖 <!--springboot项目依赖的父项目--> <parent> <groupId>org.springframewor ...

  9. 英特尔携手中国游戏开发者登陆 Unite Shanghai 2019 推动游戏产业创新

    2019 年 5 月 10 日-12 日,Unite Shanghai 2019 在上海召开.除了展示 Unity 的最新技术成就,以及出众的 Made with Unity 游戏与行业应用之外,大会 ...

  10. sql次级语句

    select upper(n_id) from nrc_news;select left(n_content,1) from nrc_news;select len(n_content) from n ...