tarjan算法

Tarjan-强连通分量

心已入冬 提交于 2020-02-26 15:37:20
这是一个漫(jian)长(nan)的过程 请大家耐心读完,相信你一定能学会 首先来介绍一下强连通分量 神奇海螺指引你: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。——百度百科 Tarjan是基于迪法师(DFS)的一种算法,可以说是一种流(du)批(liu)的操作,本蒟蒻苦哈哈的学了好几天才学会强连通分量和缩点; 在这里推荐给大家几道题: 受欢迎的牛 , 消息扩散 ; 这些题我会在后期的博客中进行详细的讲解 步入正轨: 图中{6}是第一个被发现的强连通分量,其次是{5},最后被发现的是{3,4,1,2} (顺序无所谓) Tarjan算法是解决强连通分量和缩点问题的一种比较常见的方法 接下来开始🔛一步一步的 首先给你一个图(求其中的强连通分量)(注:以下图片摘自: ~~ ) 在这里我们假设从点1开始遍历,并且将访问的点压入栈中 在进行操作之前,我们要明确Tarjan中的两个至关重要的数组:DFN和LOW; DFN[x]:表示这个点x几次被遍历到; LOW[x]

[强连通分量+Tarjan缩点]

别等时光非礼了梦想. 提交于 2020-02-12 13:10:21
强连通分量 定义:有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。 Tarjan 是 一种基于 dfs 的算法 ,图中每个强连通分量为搜索树的一棵子树 搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。 用 dfn[x] 表示 x 在 dfs 时 的时间戳 (第几个遍历到的),low[x] 表示 x 及其 子树 能 追溯 到的 最早的栈中 节点 的时间戳。 考虑到 如果 u 是某个 强连通分量的根,那么: u不存在路径可以返回到它的祖先 u的子树也不存在路径可以返回到u的祖先   所以 当 low[x] == dfn[x] 时 x 恰好 是一个 强连通分量的根。 模拟: 来源: https://www.cnblogs.com/-Wind-/p/10432368.html

Tarjan算法---强联通分量

我们两清 提交于 2020-02-12 12:25:16
1、基础知识 在有向图G,如果两个顶点间至少存在一条路径,称两个顶点 强连通 (strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个 强连通图 。非强连通图有向图的极大强连通子图,称为 强连通分量 (strongly connected components)。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4 两两可达 。{5},{6}也分别是两个强连通分量。 Tarjan算法是基于对图深度优先搜索的算法, 每个强连通分量为搜索树中的一棵子树 。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。栈中节点只有在其所属的强连通分量已经全部求出时,才会出栈。如果发现某节点u有边连到搜索树中栈里的节点v,则更新u的low 值为dfn[v](更新为low[v]也可以)。如果一个节点u已经DFS访问结束,而且此时其low值等于dfn值,则说明u可达的所有节点,都不能到达任何在u之前被DFS访问的节点 那么该节点u就是一个强连通分量在DFS搜索树中的根。此时将栈中所有节点弹出,包括u,就找到了一个强连通分量。 定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。    Low(u)=MIN{ DFN(u), Low(v),(u,v

Tarjan算法之割点

五迷三道 提交于 2019-12-03 05:25:47
定义 (均在无向图中):在一个连通图中,如果有一个顶点,删除这个点以及相关的边之后,连通块的数量增多,我们就称这个顶点为割点. 算法 tarjan。设有点x及其子节点y,如果x不是是该连通图根节点,那么当且仅当存在dfn[x] <= low[y]时,x为割点。如x为根节点,则至少有满足上式的两个y才能保证x为割点。 解释: x不为根节点,x把在x之前遍历的点和在x后遍历的点隔离,则去掉x会是原图不连通而新增连通块。 x为根节点,存在至少两个y表明走任意一个y都不可能到达其他的y。那x被取走后y之间必然互相独立,增加新连通块。 注意:由于判定符号是 <=,则不必考虑重边与父节点。 例题 Luogu-P3388 #include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> #include<algorithm> #define lson x<<1 #define rson x<<1|1 #define ll long long #define rint register int #define mid ((st[x].l + st[x].r) >> 1) using namespace std; template <typename xxx> inline void read

Tarjan算法与无向图连通性

耗尽温柔 提交于 2019-12-03 04:33:54
割边/桥 定义:删去该边后,原图分裂成大于1个联通块 求解:对于边 \(x \rightarrow y\) ,若 \(low[y] > dfn[x]\) ,则 \(x \rightarrow y\) 是桥 易错: \(dfs\) 时,带参数 \(faId\) ,表示进入 \(x\) 的边。访问 \(x\) 到达的点时,略过 \(faId\) 边双连通分量 定义:没有割边的极大子图 求解:去除所有割边 充要条件/性质: 各边都至少存在于1个简单环中 。(若某边仅在简单路径上,则有割边) 割点 定义:删去该点以及与该点相连的边之后,原图分裂成大于1个联通块 求解: 对于非根节点 \(x\) ,若存在 \(x \rightarrow y\) ,使得 \(low[y] \geq dfn[x]\) ,则 \(x\) 是割点 对于根节点 \(rt\) ,若 \(rt\) 的儿子数大于1,则 \(x\) 是割点 区别:正常的不访问 \(fa\) 的 \(dfs\) 点双联通分量 定义:没有割点的极大子图 求解: \(dfs\) 中维护1个栈。若 \(x \rightarrow y\) 时发现 \(x\) 为割点,将栈中元素出队至 \(y\) 。这些元素与 \(x\) 共同构成点双联通分量 区别:一个割点可能属于多个点双联通分量 充要条件/性质: 任意两点都至少包含在1个简单环中 。

Tarjan算法与无向图连通性

匿名 (未验证) 提交于 2019-12-03 00:15:02
定义:删去该边后,原图分裂成大于1个联通块 求解:对于边 \(x \rightarrow y\) ,若 \(low[y] > dfn[x]\) ,则 \(x \rightarrow y\) 是桥 易错: \(dfs\) 时,带参数 \(faId\) ,表示进入 \(x\) 的边。访问 \(x\) 到达的点时,略过 \(faId\) 定义:没有割边的极大子图 求解:去除所有割边 充要条件/性质: 各边都至少存在于1个简单环中 。(若某边仅在简单路径上,则有割边) 定义:删去该点以及与该点相连的边之后,原图分裂成大于1个联通块 求解: 对于非根节点 \(x\) ,若存在 \(x \rightarrow y\) ,使得 \(low[y] \geq dfn[x]\) ,则 \(x\) 是割点 对于根节点 \(rt\) ,若 \(rt\) 的儿子数大于1,则 \(x\) 是割点 区别:正常的不访问 \(fa\) 的 \(dfs\) 定义:没有割点的极大子图 求解: \(dfs\) 中维护1个栈。若 \(x \rightarrow y\) 时发现 \(x\) 为割点,将栈中元素出队至 \(y\) 。这些元素与 \(x\) 共同构成点双联通分量 区别:一个割点可能属于多个点双联通分量 充要条件/性质: 任意两点都至少包含在1个简单环中 。(假设两点间只有简单路径,则有割点) 通过 缩点 等处理

7. 图论

北城以北 提交于 2019-12-01 02:04:50
最短路 最小生成树 树的直径与最近公共祖先 基环树 负环与差分约束 Tarjan算法与无向图连通性 Tarjan算法与有向图连通性 二分图的匹配 二分图的覆盖于独立集 网络流初步 总结与练习 来源: https://www.cnblogs.com/hebust-fengyu/p/11647255.html

tarjan算法——割点

别来无恙 提交于 2019-11-30 05:29:49
简述: 从0号点开始,更新每个点能到达的最早时间戳,当 dfn[u]<=low[v] 时,u为割点 代码: 1 ///根结点为割点的条件:孩子数大于1 2 int vis[maxn],dfn[maxn],low[maxn]; 3 int n,m,a[maxn][maxn],lay,son[maxn]; 4 void tarjan(int u) { 5 low[u]=dfn[u]=++lay; 6 vis[u]=1; 7 for(int v=0;v<n;v++) 8 if(a[u][v]&&!vis[v]) { 9 tarjan(v); 10 low[u]=min(low[u],low[v]); 11 if(dfn[u]<=low[v]) 12 son[u]++; 13 } 14 else if(a[u][v])low[u]=min(dfn[v],low[u]); 15 } View Code 来源: https://www.cnblogs.com/wuliking/p/11561863.html

浅见Tarjan算法与无向图连通性

China☆狼群 提交于 2019-11-28 10:35:36
无向图的割点和桥 定义 割点:删除这个点时图将不再连通 割边:删除这条便时图将不再连通 时间戳 在图的深度优先搜索中的顺序(第几个被访问) 搜索树 在深搜时形成的树 图一为一张无向连通图,中间的为起点,红边为“发生递归”的边 图二就是搜索树了,编号为时间戳 追溯值 追溯值为low[],low[x]表示x及x的能到达的节点的dfn最小值 割边的判定法则 无向图(x, y)是桥,当且仅当在搜索树上存在x的一个子节点y,满足: low[y] > dfn[x] 模板 割点判定法则 如果x并不是树的根节点,则x是割点当且仅当搜索树上存在一个x的子节点y,满足: low[y] >= dfn[x] 特别的,当x为树的根节点且有2个及以上的子树时,x也为割点 模板 无向图的双联通分量 若一张无向联通图不存在割点,则是 点双联通图 若一张无向联通图不存在割边,则是 边双联通图 无向图的极大点双联通子图叫做 “点双联通分量” 无向图的极大边双联通子图叫做 “边双联通分量” 定理 一张无向连通图是“点双联通图”,当且仅当满足下列2个条件之一: 1 图的节点数<=2 2 图中的任意两点有不小于2条的不重复的路径可以互相到达,即在一个简单环中 边双求法 只需要求出图中所有的割边,把这些割边删掉后,会出现若干个连通块,每一个连通块就是一个边双 边双模板 点双求法

Tarjan算法求有向图强连通分量并缩点

非 Y 不嫁゛ 提交于 2019-11-27 05:40:20
// Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N = 100010, M = 1000010; // int ver[M], Next[M], head[N], dfn[N], low[N]; int stack[N], ins[N], c[N]; int vc[M], nc[M], hc[N], tc; //强连通分量 vector<int> scc[N]; int n, m, tot, num, top, cnt; void add(int x, int y) { ver[++tot] = y, Next[tot] = head[x], head[x] = tot; } //缩点后建图 void add_c(int x, int y) { vc[++tc] = y, nc[tc] = hc[x], hc[x] = tc; } void tarjan(int x) { dfn[x] = low[x] = ++num; stack[++top] = x, ins[x] = 1;//标记x点 for (int