大白书中无向图的点双联通分量(BCC)模板的分析与理解
对于一个无向图,如果任意两点至少存在两条点不重复(除起点和终点外无公共点)的路径,则这个图就是点双联通。
这个要求等价于任意两条边都存在于一个简单环(即同一个点不能在圈中出现两次)中,即内部无割点。
那么算法首先要求出割点。
从代码中可以看出:只要求出割点,就开始组一个bcc中。
如果割点两侧都不存在环的话会怎么处理呢?
代码中相邻的割点(或者是割点和根节点)也被当做一个bcc处理。
bccno[i]为点i所在的bcc序号,那么割点的bccno为多少呢?
割点的bccno没有意义,割点存在于多个bcc中。
割点:删除这个点后,联通分量增加,那么这个点就是割点。
在图的dfs搜索树中,非根节点u的子节点v没有方向边(dfs搜索树中后代指向祖先的边)返回u的祖先,那么u就是割点。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<vector>
using namespace std;
const int MAXN=1e3+,INF=0x3f3f3f3f,MOD=1e9+;
int n;
int vis[MAXN][MAXN];
vector<int>G[MAXN];
int dfs_color=; ///dfs时间戳
int pre[MAXN],post[MAXN];
int bcc_cnt=; ///联通分量
int low[MAXN]; ///u及其后代所能连回的最早祖先的pre值
int iscut[MAXN]; ///割点
vector<pair<int,int> >birdge; ///桥
struct edge
{
int u,v;
};
stack<edge>S;
int bccno[MAXN]; ///点所在的双联通分量
vector<int>bcc[MAXN]; ///双联通分量
int dfs(int u,int fa)
{
int lowu=pre[u]=++dfs_color;
int child=;
for(int i=; i<G[u].size(); i++)
{
int v=G[u][i];
edge e=(edge)
{
u,v
};
if(!pre[v])
{
S.push(e);
child++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u])
{
iscut[u]=true;
if(lowv>pre[u]) birdge.push_back(make_pair(u,v));
bcc_cnt++;
bcc[bcc_cnt].clear();
while(!S.empty())
{
edge x=S.top();
S.pop();
if(bccno[x.u]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(x.u);
bccno[x.u]=bcc_cnt;
}
if(bccno[x.v]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(x.v);
bccno[x.v]=bcc_cnt;
}
if(x.u==u&&x.v==v) break;
}
}
}
else if(pre[v]<pre[u]&&v!=fa)
{
S.push(e);
lowu=min(lowu,pre[v]);
}
}
if(fa<&&child==) iscut[u]=;
low[u]=lowu;
return low[u];
}
void find_bcc()
{
bcc_cnt=;
dfs_color=;
memset(pre,,sizeof(pre));
memset(iscut,,sizeof(iscut));
memset(bccno,,sizeof(bccno));
for(int i=; i<=n; i++)
if(!pre[i]) dfs(i,-);
}
void init(int m)
{
memset(vis,,sizeof(vis));
for(int i=; i<=n; i++) G[i].clear();
birdge.clear();
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
int main()
{
int m;
while(scanf("%d%d",&n,&m))
{
init(m);
find_bcc();
for(int i=; i<=bcc_cnt; i++)
{
cout<<i<<":";
for(int j=; j<bcc[i].size(); j++)
cout<<bcc[i][j]<<" ";
cout<<endl;
}
}
return ;
}
大白书中无向图的点双联通分量(BCC)模板的分析与理解的更多相关文章
- 无向图边双联通分量 tarjan 模板
#include <bits/stdc++.h> using namespace std; const int MAXN = 100005; const int MAXM = 500005 ...
- 点双联通分量(BCC)的正确姿势
Tarjan求点双连通分量 - 李昊哲
- Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定
题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- 图连通性【tarjan点双连通分量、边双联通分量】【无向图】
根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...
- Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)
Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...
- Tarjan 强连通分量 及 双联通分量(求割点,割边)
Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1) 有向图的强联通分量 (2) 无向图的双联通分量(求割点,桥) ...
随机推荐
- c语言实现:三子棋
问题描述:两个游戏者在3*3棋盘里轮流作标记,如果一个人在行,列或者两个对角线可以作三个标记,则为获胜. 我们首先得打印菜单供玩家选择(可以选择玩游戏或者退出游戏) void menu() { pri ...
- HU-1043
http://acm.hdu.edu.cn/showproblem.php?pid=1043 由于HDU这里的涉及多组数据,而每组数据按照一般的bfs()做法,即遍历每一种可行方案都保存一次路径,直到 ...
- 在虚拟机上运行zookeeper的过程中,xshell连接不上虚拟机
之后网上的各种方法,都没用 如图,就是第一个网卡配置文件.下面又具体的详解.网上有说让把Onboot改成yes,而我的本来就是yes,就没该, 之后我对比了我原来电脑你虚拟机的网卡配置文件,我发现on ...
- nodeJs 使用 express-http-proxy 转发请求
开发过程中经常需要用到 nodeJs做转发层 使用express配合 express-http-proxy 可以轻松的完成转发 使用过程: 安装 express-http-proxy npm inst ...
- xml是什么
XML(Extensible Markup Language)是可扩展标记语言,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言 ...
- mysql监控执行的sql语句
转载 https://blog.csdn.net/nzjdsds/article/details/77513869 MySQL用SQL开启general_log并设置路径 2017年08月24日 00 ...
- 39_redux_counter应用_redux版本
一.下载 要想使用redux,首先要下载它 npm install --save redux 二.核心API 1.createStore() 作用:创建包含指定reducer的store对象 编码:i ...
- Linux OS7 常用
查看防火墙状态: firewall-cmd --state;停止firewall: systemctl stop firewalld.service;禁止firewall开机启动:systemctl ...
- MATLAB入门笔记
% MATLAB:MATLAB 为 Matrix Laboratory ,用来处理矩阵可编程可实现算法逻辑的计算工具% % eg:1 绘制正弦和余弦曲线x=[0:0.1:4*pi]; %建立角度向量p ...
- python字符串 列表 元组 字典相关操作函数总结
1.字符串操作函数 find 在字符串中查找子串,找到首次出现的位置,返回下标,找不到返回-1 rfind 从右边查找 join 连接字符串数组 replace 用指定内容替换指定内容,可以指定次数 ...