定义分析

  • 给定一个无向连通图\(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. 强大的动态SQL

    1 动态SQL# 那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.My ...

  2. 隐语义模型LFM

      隐语义模型是通过隐含特征,联系用户和物品,基于用户的特征对物品进行自动聚类,然后在用户感兴趣的类中选择物品推荐给用户. 对于推荐系统,常用的算法: USER-CF:给用户推荐和他兴趣相似的用户喜欢 ...

  3. CentOS Linux SVN服务器 配置用户目录访问 权限 Authorization failed

    SVN 修改 aurhz 文件设置用户目录访问权限格式: [/code] user=rw user 用户对code目录拥有读和写的权限. 但是访问 svn://192.168.1.59 的时候却提示A ...

  4. Mac苹果电脑单片机开发

    1.安装虚拟机 可以阅读往期文章:Mac苹果电脑安装虚拟机 2.在虚拟机上安装CH340驱动,keil4,PZ-ISP, 下载 CH340驱动安装  下载keil4破解及汉化  下载普中科技烧录软件

  5. JavaDailyReports10_14

    1 package Test; 2 3 import java.util.Scanner; 4 5 public class Main { 6 7 public static void main(St ...

  6. Mybatis利用Intercepter实现物理分页

    一.Interceptor介绍 Mybatis 允许用户使用自定义拦截器对SQL语句执行过程中的某一点进行拦截.默认情况,可以拦截的方法如下: Executor 中的 update().query() ...

  7. JavaScript--总结二(流程控制+调试)

    表达式和语句 表达式------ 一个表达式可以产生一个值,有可能式运算,函数调用,有可能是字面量.表达式可以放在任何需要值的地方 语句----- 语句可以理解为一个行为,循环语句和判断语句就是典型的 ...

  8. String被final修饰

    源码:

  9. Spring Security OAuth2.0认证授权一:框架搭建和认证测试

    一.OAuth2.0介绍 OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不 需要将用户名和密码提供给第三方应用或分享他们数据的所有内容. 1.s ...

  10. spark知识点_datasources

    来自官网DataFrames.DataSets.SQL,即sparkSQL模块. 通过dataframe接口,sparkSQL支持多种数据源的操作.可以把dataframe注册为临时视图,也可以通过关 ...