定义分析

  • 给定一个无向连通图\(G=(V,E)\)

  • 对于\(x\in Y\),如果删去\(x\)及与\(x\)相连的边后,\(G\)分裂为两个或者两个以上的不连通子图,那么称\(x\)为\(G\)的割点

  • 对于\((x,y)\in E\),如果删去\((x,y)\)后,\(G\)分裂为两个不连通的子图,那么就称\((x,y)\)为\(G\)的桥或者割边

  • 一般无向图(不保证连通)的割点和桥 指的是各个连通块的割点和桥

在这个图中,\(1,6\)号结点为割点,\((1,6),(6,7)\)是桥

概念引入(Tarjan独特概念)

  • 时间戳:对一张无向连通图进行DFS,使每个点只经过一遍,并且按照每个点第一次被访问的时间顺序依次标号(也就是他们的DFS序),这个标号被称为时间戳,记为\(dfs_x\).

  • 搜索树:在时间戳形成的DFS过程中,我们发现所有构成递归的边构成了一棵树,称之为无向连通图的搜索树.

  • 追溯值:设\(subtree(x)\)表示搜索树中以\(x\)为根的子树,节点\(u\)的追溯值我们定义为\(low_u\),定义为一下结点时间戳的最小值.

    1、位于\(subtree(x)\)中的节点.

    2、通过一条不在搜索树上的边,可以到达\(subtree(x)\)的节点.

构建方法(追溯值,时间戳)

  • 第一次访问到一个节点\(x\)的时候,首先我们令\(low_x=dfn_x\).

  • 然后,我们继续考虑与\(x\)相邻的每一条边,如果没有被访问过,那么就递归

    地却访问他们,回溯是更新\(low_x\).

  • 如果\(y\in subtree(x)\),那么\(low_x=min(low_x,low_y)\).

  • 否则\(low_x=min(low_x,dfn_y)\).

割点的判定

  • 如果\(x\)不是搜索树上的根节点,那么\(x\)的割点判定条件为当且仅当搜索树上的一个子节点\(y\)满足
\[dfn_x\leq low_y
\]
  • 解释:(请先理解好追溯值定义)这个公式表示的意思是在\(subtree(y)\)中的点如果不经过\(x\)那么就无法到达比\(x\)更早访问过的点。

  • 特殊情况:如果\(x是根节点\),那么\(x\)是割点当且仅当搜索树上的两个子节点\(y\)满足上述条件时成立,表示这两个子节点无法互相到达

桥的判定

  • 无向边\((x,y)\)是桥,当且仅当\((x,y)\),位于搜索树上,并且在搜索树上\(x\)的一个子节点\(y\)满足
\[dfn_x<low_y
\]
  • 表示从\(subtree(y)\)出发,在不经过\((x,y)\)的前提下,无论是怎么走都无法到达\(x\)或者比\(x\)更早访问过的节点

  • 当然,一个简单环里面的边一定不是桥,因为他是圈圈!!!

  • 不在搜索树上的边至少都位于至少一个环中,因为不在搜索树上的边那么就表示它一定是连接到了已经被搜索过的点,所以当通过那个点的时候一定能在回到它本身,所以一定在至少一个环中

割点,桥判定代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+9;
struct node{
int last;
int to;
}e[N*2];
int head[N],vis[N],dfn[N],low[N],cut[N],cnt,poi,tot;
int n,m,root;
void add(int from,int to)
{
e[++cnt].last=head[from];
e[cnt].to=to;
head[from]=cnt;
}
void tarjan(int x)
{
dfn[x]=low[x]=++poi;
int flag=0;//根节点的判断
for(int i=head[x];i;i=e[i].last)
{
int v=e[i].to;
if(!dfn[v])//没有打时间戳说明未被搜索到过
{
tarjan(v);
low[x]=min(low[v],low[x]);
if(low[v]>=dfn[x])
{
flag++;
if(x!=root||flag>1)
{
cut[x]=1;
}
}
}
else low[x]=min(low[x],dfn[v]);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
if(x==y) continue;
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
root=i;
tarjan(i);
}
}
for(int i=1;i<=n;i++)
{
if(cut[i]) tot++;
}
cout<<tot<<endl;
for(int i=1;i<=n;i++)
{
if(cut[i]) cout<<i<<" "; //输出割点
}
return 0;
}``` ```void tarjan(int x, int in_edge) //求桥
{
dfn[x] = low[x] = ++num;
for (int i = head[x]; i; i = Next[i]) {
int y = ver[i];
if (!dfn[y]) {
tarjan(y, i);
low[x] = min(low[x], low[y]);
if (low[y] > dfn[x])
bridge[i] = bridge[i ^ 1] = true;
}
else if (i != (in_edge ^ 1))
low[x] = min(low[x], dfn[y]);
}
}

tarjan 复习笔记 割点与桥的更多相关文章

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

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

  2. tarjan复习笔记

    tarjan复习笔记 (关于tarjan读法,优雅一点读塔洋,接地气一点读塔尖) 0. 连通分量 有向图: 强连通分量(SCC)是个啥 就是一张图里面两个点能互相达到,那么这两个点在同一个强连通分量里 ...

  3. 学习笔记--Tarjan算法之割点与桥

    前言 图论中联通性相关问题往往会牵扯到无向图的割点与桥或是下一篇博客会讲的强连通分量,强有力的\(Tarjan\)算法能在\(O(n)\)的时间找到割点与桥 定义 若您是第一次了解\(Tarjan\) ...

  4. Tarjan求无向图割点、桥详解

    tarjan算法--求无向图的割点和桥   一.基本概念 1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不 ...

  5. tarjan复习笔记 双连通分量,强连通分量

    声明:图自行参考割点和桥QVQ 双连通分量 如果一个无向连通图\(G=(V,E)\)中不存在割点(相对于这个图),则称它为点双连通图 如果一个无向连通图\(G=(V,E)\)中不存在割边(相对于这个图 ...

  6. 求无向图的割点和桥模板(tarjan)

    一.基本概念 1.桥:若无向连通图的边割集中只有一条边,则称这条边为割边或者桥 (离散书上给出的定义.. 通俗的来说就是无向连通图中的某条边,删除后得到的新图联通分支至少为2(即不连通: 2.割点:若 ...

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

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

  8. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  9. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

随机推荐

  1. 在jsp页面动态添加,删除文本框模块

    jsp代码============ <table class="crud-content-info" > <tr > <td align=" ...

  2. [leetcode]109. Convert Sorted List to Binary Search Tree链表构建二叉搜索树

    二叉树的各种遍历方式都是可以建立二叉树的,例如中序遍历,就是在第一步建立左子树,中间第二步建立新的节点,第三步构建右子树 此题利用二叉搜索树的中序遍历是递增序列的特点,而链表正好就是递增序列,从左子树 ...

  3. C语言输入字符串

    首先强调一点,C语言没有字符串的概念!所谓的字符串实际上还是以数组形式保存的. 方法1  -- 通过"%s"输入 优点:简单明了,输入字符只要不大于数组长度都可以. #includ ...

  4. 深入理解linux-free命令原理(2)

    linux free 命令用法说明 概述: 这篇文章比较深入的从free为起点  折射出的一些概念:比如  buff/cache是怎么一回事[涉及内存页等话题]:  available这个参数与fre ...

  5. UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读

    UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读 UNION: 一种评估开放故事生成无参考文本依赖me ...

  6. Spring Cloud Hystrix原理篇(十一)

    一.Hystrix处理流程 Hystrix流程图如下: Hystrix整个工作流如下: 构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在 ...

  7. Linux操作系统的文件目录结构

    一 --- 导读 首先记住一句经典的话:"linux世界中,万事万物皆为文件" 二---linux的目录结构示意图和windows下的目录结构示意图(本图需要背诵) 三---各目录 ...

  8. Pytest测试框架(三):pytest fixture 用法

    xUnit style 结构的 fixture用于初始化测试函数, pytest fixture是对传统的 xUnit 架构的setup/teardown功能的改进.pytest fixture为测试 ...

  9. 第14章节 BJROBOT karto 算法构建地图【ROS全开源阿克曼转向智能网联无人驾驶车】

    建地图前说明:请确保你的小车已经校正好 IMU.角速度.线速度,虚拟机配置好 ROS 网络的前提进行,否则会造成构建地图无边界.虚拟机端无法正常收到小车主控端发布的话题数据等异常情况!! 1.把小车平 ...

  10. Ubuntu无法ssh远程连接问题 (转)

    [系统]Ubuntu 12.04 server [问题描述]新安装的Ubuntu系统无法直接通过ssh远程连接. [解决办法] 新安装的Ubuntu系统并未安装ssh-server服务,需要自行安装, ...