[学习笔记]tarjan求割边

上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ

所以,本文介绍求割边(又称桥).

的定义同求有向图强连通分量.

枚举当前点的所有邻接点:

1.如果某个邻接点未被访问过,则访问,并在回溯后更新

2.如果某个邻接点已被访问过,则更新

对于当前节点,如果邻接点中存在一点满足(向上无法到达祖先)说明为一条割边.

inline void tarjan(int u,int fa){
    dfn[u]=low[u]=++cnt;
    for(int i=g[u];i;i=e[i].nxt)
        if(!dfn[e[i].to]){
            tarjan(e[i].to,u);
            low[u]=min(low[u],low[e[i].to]);
            if(low[e[i].to]>dfn[u]) cut[e[i].n]=true;
        }
        else if(e[i].to!=fa)
            low[u]=min(low[u],dfn[e[i].to]);
}
时间: 2024-11-05 12:20:29

[学习笔记]tarjan求割边的相关文章

<学习笔记> tarjan 求强连通分量

时间复杂度 O(n+m) dfs 求解. 定义 dfn[n]为n当前的时间戳,low[n]为n最早能追溯到的时间戳,可知 1 for(int i=first[n];i;i=next[i]) 2 { 3 if(!dfn[Rode[i].t]) 4 { 5 Tarjan(Rode[i].t); 6 low[n]=min(low[n],low[Rode[i].t]); 7 } 8 else 9 if(Instack[Rode[i].t]) low[n]=min(low[n],dfn[Rode[i].t

tarjan求割边割点

tarjan求割边割点 内容及代码来自http://m.blog.csdn.net/article/details?id=51984469 割边:在连通图中,删除了连通图的某条边后,图不再连通.这样的边被称为割边,也叫做桥.割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通.这样的点被称为割点.DFS搜索树:用DFS对图进行遍历时,按照遍历次序的不同,我们可以得到一棵DFS搜索树. 树边:在搜索树中的蓝色线所示,可理解为在DFS过程中访问未访问节点时所经过的边,也称为父子边

ZOJ 1588 Burning Bridges (tarjan求割边)

题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] < low[v],则边(u,v)是割边. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace st

Burning Bridges 求tarjan求割边

Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 #define clr(a) memset(a,0,sizeof(a)) 4 #define N 10005 5 #define M 100005 6 #define MIN(a,b) ((a)>(b)?(b):(a)) 7 typedef struct NodeStr //边结点 8 { 9 int

Groovy学习笔记-布尔求值

1.判断字符串为null或空字符串 def str = null if(str) println 'str is not null' else println 'str is null' str = '' if(str) println 'str is not null' else println 'str is null' /*output str is null str is null */ 2.集合是否为空或Count ==0 list = null if(list) println 'l

tarjan求lca的神奇

题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每行包含两个正整数x.y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树). 接下来M行每行包含两个正整数a.b,表示询问a结点和b结点的最近公共祖先. 输出格式: 输出包含M行,每行包含一个正整数,依次为每一个询问的结果. 输入输出样例 输入样例#1: 5 5 4 3 1 2 4 5

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

博主图论比较弱,搜了模版也不会用... 所以决心学习以下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结点的时间.一个无向图dfs会形成一个森林,当图只有一个连通分量时,就只有一棵树. 由于在无向图中,除了树边,其他都是反向边.可以画个图感受一下,可以反证的,如果有其他类型的边,那么dfs先沿着那些边跑图的,那么那些边就不存在. 如果结点是树根,那么它是割点的充要条件就是它有两个子结点. 定理 对于

ZOJ Problem - 2588 Burning Bridges tarjan算法求割边

题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍). 需要注意的就是此处有多重边,题目中要求输出确定的不能被删除的边,而多重边的保留不是可以确定的,所以多重边都是不可以被保留的,我们可以在邻接表做一个flag的标记,判断他是不是多重边. 注意建图的时候数组应该是m × 2,因为这里是无向边,当心RE! 注意输出的时候编号是必须要拍好序再输出. 还有

tarjan[强连通分量][求割边割点][缩点]

强连通分量: 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=100000+15; 5 struct Edge { 6 int x,y,next; 7 Edge(int x=0,int y=0,int next=0): 8 x(x),y(y),next(next) {} 9 } edge[maxn]; 10 int sumedge,head[maxn]; 11 int n,m; 12 int ins(in