图连通性【tarjan点双连通分量、边双联通分量】【无向图】
根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习。
有割点不一定有割边,有割边不一定有割点。
理解low[u]的定义很重要。
1.无向图求割点、点双联通分量:
如果对一条边(x,y),如果low[y]>=dfn[x],表示搜索树中y为根的子树必须要通过x才能到达树的上端,则x必为割点。
x属于多个点双联通分量,所以出栈的时候保留x(所以栈出到y就好!否则可能会把其他支路的节点一起出栈)。
附上一个小例子。
这个打个模板吧。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=;
int n,m,al,cnt,num,sl,dfn[N],low[N],vis[N],s[N],first[N],b[N][];
struct node{int x,y,next;}a[N*]; void ins(int x,int y)
{
a[++al].x=x;a[++al].y=y;
a[al].next=first[x];first[x]=al;
} int minn(int x,int y){return x<y ? x:y;} void tarjan(int x)
{
dfn[x]=low[x]=++num;
s[++sl]=x;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(!dfn[y])
{
tarjan(y);
low[x]=minn(low[x],low[y]);
if(low[y]>=dfn[x])//key
{
cnt++;
b[cnt][++b[cnt][]]=x;
while()
{
int z=s[sl--];
b[cnt][++b[cnt][]]=z;
if(z==y) break;
}
}
}
else low[x]=minn(low[x],low[y]);
}
} int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);
al=;
memset(first,,sizeof(first));
num=;cnt=;sl=;
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
memset(b,,sizeof(b));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<=cnt;i++)
{
for(int j=;j<=b[i][];j++)
printf("%d ",b[i][j]);
printf("\n");
}
return ;
}
2.无向图求割边、边双联通分量:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=;
int n,m,al,cnt,num,sl,dfn[N],low[N],vis[N],s[N],first[N],b[N][];
struct node{int x,y,next,tmp;}a[N*]; void ins(int x,int y)
{
a[++al].x=x;a[al].y=y;a[al].tmp=;
a[al].next=first[x];first[x]=al;
} int minn(int x,int y){return x<y ? x:y;} void tarjan(int x)
{
dfn[x]=low[x]=++num;
s[++sl]=x;
for(int i=first[x];i;i=a[i].next)
{
if(a[i].tmp) continue;
a[i].tmp=;
a[(i%)== ? i-:i+].tmp=;//key
int y=a[i].y;
if(!dfn[y])
{
tarjan(y);
low[x]=minn(low[x],low[y]);
if(low[y]>dfn[x])//key
{
cnt++;
while()
{
int z=s[sl--];
b[cnt][++b[cnt][]]=z;
if(z==y) break;
}
}
}
else low[x]=minn(low[x],low[y]);//前提:x->y不是搜索树上的边,故前面应该把走过的边的反向边去掉。
}
} int main()
{
//freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);
al=;
memset(first,,sizeof(first));
num=;cnt=;sl=;
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
memset(b,,sizeof(b));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
if(sl) //key
{
cnt++;
b[cnt][]=sl;
for(int j=;j<=sl;j++) b[cnt][j]=s[j];
sl=;
}
}
}
for(int i=;i<=cnt;i++)
{
for(int j=;j<=b[i][];j++)
printf("%d ",b[i][j]);
printf("\n");
}
return ;
}
图连通性【tarjan点双连通分量、边双联通分量】【无向图】的更多相关文章
- 双连通分量(点-双连通分量&边-双连通分量)
概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...
- [HIHO1184]连通性二·边的双连通分量(双连通分量)
题目链接:http://hihocoder.com/problemset/problem/1184 题意裸,写个博客记下输出姿势. /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mi ...
- 图->连通性->关节点和重连通分量
文字描述 相关定义:假若在删去顶点v以及和v相关联的各边之后,将图的一个连通分量分割成两个或两个以上的连通分量,则称顶点v为该图的一个关节点.一个没有关节点的连通图称为重连通图. 在重连通图上,任意一 ...
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...
- Tarjan算法初探(3):求割点与桥以及双连通分量
接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的 ...
- [Tarjan系列] Tarjan算法求无向图的双连通分量
这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- poj 3177 Redundant Paths(边双连通分量+缩点)
链接:http://poj.org/problem?id=3177 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任 ...
- 无向图的边双连通分量(EBC)
嗯,首先边双连通分量(双连通分量之一)是:在一个无向图中,去掉任意的一条边都不会改变此图的连通性,即不存在桥(连通两个边双连通分量的边),称作边双连通分量.一个无向图的每一个极大边双连通子图称作此无向 ...
- DFS的运用(二分图判定、无向图的割顶和桥,双连通分量,有向图的强连通分量)
一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISI ...
随机推荐
- Java学习个人备忘录之多线程
进程:正在进行中的程序(直译). 线程:就是进程中一个负责程序执行的控制单元(执行路径) 一个进程中可以有多个执行路径,称之为多线程. 一个进程中至少要有一个线程. 开启多个线程是为了同时运行多部分代 ...
- 事后分析报告(M2阶段)
我们的项目是自选项目,一款名为备忘录锁屏MemoryDebris的软件. 在第二轮的迭代中,由于各科的大作业都集中在这一段时间,所以这段时间各个组员间的负担都比较大,但是在大家共同努力,最终我们还是交 ...
- Ubuntu 配置 Android 开发 环境
. 果断换Ubuntu了, Ubuntu的截图效果不好, 不能设置阴影 ... 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article ...
- iOS APP中第三方APP调用自己的APP,打开文件
根据需求需要在项目中要打开word.pdf.excel等文件,在info.plist文件中添加 <key>CFBundleDocumentTypes</key> <arr ...
- SQL SERVER技术内幕之4 子查询
最外层查询的结果集会返回给调用者,称为外部查询.内部查询的结果是供外部查询使用的,也称为子查询.子查询可以分成独立子查询和相关子查询两类.独立子查询不依赖于它所属的外部查询,而相关子查询则须依赖它所属 ...
- 主流 Kubernetes 发行版梳理
2014 年,Kubernetes 作为内部 Google orchestrator Borg 开源版本推出,目前已是最成功和发展最快的 IT 基础架构项目之一.2018 年,Kubernetes 已 ...
- DELPHI的MEMO组件
位于Standard选项卡上,它是对EDIT控件的扩展,可以对多行文本进行显示.输入 和编辑. Lines属性: 该属性实际上为TStrings类型的对象,用来存放Memo对象的文本 TStrings ...
- 编译 python 生成静态库 libpython2.7.so
由于我们是C++作驱动的Python开发,驱动需要加上Python静态库libpython2.7.so.libpython2.7.so.1.0.libpython2.7.a.此处我想在python源码 ...
- [洛谷P3878][TJOI2010]分金币
题目大意:把$n(n\leqslant30)$个数分成两组,两组个数最多相差$1$,求出两组元素差的绝对值最小使多少 题解:模拟退火 卡点:$\exp$中的两个数相减写反,导致$\exp(x)$中的$ ...
- 2016多校联合训练1 B题Chess (博弈论 SG函数)
题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外 ...