博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法笔记--无向图的桥、割点、边双连通分量和点双连通分量
阅读量:6594 次
发布时间:2019-06-24

本文共 2783 字,大约阅读时间需要 9 分钟。

概念:

桥:无向图中删去一条边使得图不再联通,则这条边称为桥

割点:无向图中删去一个点使得图不再联通,则这个点称为割点

算法:

运用到tarjan算法

关于tarjan算法: 

求桥: 对于一条边 u -> v, 如果它是树边low[v] > dfn[u], 则这条边为桥, 因为删去了这条边, v无法到达u以及u以上的点

求割点:对于一个点u, 如果它是根节点,且子树个数大于等于2, 则u是割点, 因为删去这个点后它的子树之间不能互相到达

          如果它不是根节点, 假设它有一个儿子为v, 如果low[v] >= dfn[u], 则u是割点, 因为删去u后v无法到达u以上的点

模板:

const int N = 1e5 + 5;vector
> g[N];int low[N], dfn[N], tot = 0;pair
fa[N];bool is_cut[N], is_bridge[N];void tarjan(int u, pair
o) { fa[u] = o; dfn[u] = low[u] = ++tot; for (pair
p : g[u]) { int v = p.fi; if(!dfn[v]) { tarjan(v, {u, p.se}); low[u] = min(low[u], low[v]); } else if(v != o.fi) low[u] = min(low[u], dfn[v]); }}void solve(int n) { tarjan(1, {
1, 1}); //求割点 int son = 0; for (int v = 2; v <= n; v++) { if(fa[v].fi == 1) son++; else { int u = fa[v].fi; if(low[v] >= dfn[u]) is_cut[u] = true; } } if(son >= 2) is_cut[1] = true; //求桥 for (int v = 2; v <= n; v++) { int u = fa[v].fi; if(low[v] > dfn[u]) is_bridge[fa[v].se] = true; }}

 概念:

边双连通分量:不存在桥的无向图为边双连通图, 极大边双连通图为边双连通分量

思路:边双联通分量与强联通分量类似,一个无向图, 一个有向图

模板:

const int N = 1e5 + 5;vector
g[N];vector
bcc[N];bool vis[N];int low[N], dfn[N], stk[N], tot = 0, top = 0, cnt = 0;void tarjan(int u, int fa) { low[u] = dfn[u] = ++tot; stk[++top] = u; vis[u] = true; for (int v : g[u]) { if(v == fa) continue; if(!dfn[v]) { tarjan(v, u); low[u] = min(low[u], low[v]); } else if(vis[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) { ++cnt; while(stk[top] != u) vis[stk[top]] = false, bcc[cnt].pb(stk[top--]); vis[stk[top]] = false, bcc[cnt].pb(stk[top--]); }}

点双连通分量:不存在割点的无向图为点双连通图, 极大点双连通图为点双连通分量

模板:

const int N = 1e5 + 5;vector
g[N];vector
> bcc[N];int low[N], dfn[N], tot = 0, top = 0, cnt = 0;pair
stk[N];void tarjan(int u, int fa) { low[u] = dfn[u] = ++tot; for (int v : g[u]) { pair
e = {u, v}; if(!dfn[v]) { stk[++top] = e; tarjan(v, u); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { cnt++; while(stk[top] != e) { bcc[cnt].push_back(stk[top--]); } bcc[cnt].push_back(stk[top--]); } } else if(v != fa ) { if(dfn[v] < dfn[u]) stk[++top] = e, low[u] = min(low[u], dfn[v]); } }}

 

转载于:https://www.cnblogs.com/widsom/p/10009709.html

你可能感兴趣的文章
modsecurity(尚不完善)
查看>>
获取.propertys文件获取文件内容
查看>>
Redis3.0.5配置文件详解
查看>>
Know about Oracle RAC Heartbeat
查看>>
JQuery——实现Ajax应用
查看>>
前端05.js入门之BOM对象与DOM对象。
查看>>
oracle kill所有plsql developer进程
查看>>
keepalived双机热备原理及实例部署LVS+keepalived
查看>>
曲线学习PyQt5方案一
查看>>
OpenCV学习】矩阵运算和操作2
查看>>
nginx+ffmpeg搭建rtmp转播rtsp流的flash服务器
查看>>
关于在arm裸板编程时使用printf问题的解决方法
查看>>
开源人工智能技术将改变一切
查看>>
2015 上半年 JavaScript 使用统计数据
查看>>
《Python算法教程》——1.6 如果您感兴趣
查看>>
深度解析Java8 – AbstractQueuedSynchronizer的实现分析(下)
查看>>
SSH原理与运用(一):远程登录
查看>>
Spring Framework 4.2 中的新功能和增强功能
查看>>
动态代理解决网站字符集编码
查看>>
Hbuilder--让手爽,飞一般的编码(二)
查看>>