运用Tarjan算法,求解图的点/边双连通分量。

1、点双连通分量【块】

割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义。

 typedef struct{  //栈结点结构  保存边
int front;
int rear;
}BNode;
BNode block_edge[MAXL];
int top; //栈指针,指向下一个空位
int num_block; //块计数
int b1,b2; //存储块中的边 辅助信息[全局变量]
void add(int *top,int front,int rear) //边入栈
{
if(*top < MAXL)
{
block_edge[*top].front=front;
block_edge[*top].rear=rear;
(*top)++;
}
}
void del(int *top) //边出栈
{
if(*top > )
{
(*top)--;
b1=block_edge[*top].front;
b2=block_edge[*top].rear;
}
} void init_dfnlow(void) //初始化
{
depth=;
root=; //【**可自定义**】若不输出割点,可以不用
num_block=;
for(int i=;i<ALG->n;i++)
{
vis[i]=;
dfn[i]=low[i]=-;
} top=;
b1=b2=-;
for(int j=;j<ALG->e;j++)
{
block_edge[j].front=;
block_edge[j].rear =;
}
} void cutblock_Tarjan(int u,int parent)
{
int son;
ENode *ptr=(ENode *)malloc(sizeof(ENode)); dfn[u]=low[u]=depth++;
vis[u]=;
ptr=ALG->vlist[u].firstedge;
while(ptr!=NULL)
{
son=ptr->key;
if(son!=parent && dfn[son]<dfn[u]) //非树边&&回退边
{ // 新边压栈,v!=w是防止重复计算无向图中同一条树边
add(&top,u,son); //dfn[w]<dfn[u] 是防止重复计算回退边
if(!vis[son])
{
cutblock_Tarjan(son,u);
low[u]=MIN(low[u],low[son]);
if(low[son] >= dfn[u]) //u是割点,输出连通分支,包括(u,son)
{
num_block++;
do{
del(&top);
printf("<%c,%c> ",ALG->vlist[b1].vertex,ALG->vlist[b2].vertex);
}while(!(u==b1 && son==b2));
printf("\n"); /* del(&top); //两种不同的输出形式
while(!((u==b1) && (son==b2)))
{
printf("<%c,%c>,",ALG->vlist[b1].vertex,ALG->vlist[b2].vertex);
del(&top);
}
printf("<%c,%c>\n",ALG->vlist[u].vertex,ALG->vlist[son].vertex); */
}
}
else if(son != parent)
{
low[u]=MIN(low[u],dfn[son]);
}
} ptr=ptr->next;
}
}

2、边双连通分量【缩点】

某一个点只能在一个“缩点”内,“缩点”时不包括当前节点u,分量以顶点的形式输出。

 int stack[MAXL];  //栈用于缓存缩点,存放编号
int top;
int bnode[MAXL]; //用于存储缩点,存放编号
int count_bnodeele; //分量元素计数
void init_Tarjan(void)
{
depth=;
num_bridge=;
for(int i=;i<ALG->n;i++)
{
dfn[i]=low[i]=-;
vis[i]=;
// bridge[i]=0;
stack[i]=-;
}
top=;
} void init_bnode(void) //缩点初始化
{
count_bnodeele=;
for(int i=;i<ALG->n;i++)
bnode[i]=-;
} void bridge_node_Tarjan(int u,int parent)
{
int son;
ENode *ptr=(ENode*)malloc(sizeof(ENode)); dfn[u]=low[u]=depth++; //访问+标记+入栈+遍历
vis[u]=;
stack[top++]=u;
ptr=ALG->vlist[u].firstedge;
while(ptr!=NULL)
{
son=ptr->key;
if(son!=parent && dfn[son]<dfn[u])
{
if(!vis[son])
{
bridge_node_Tarjan(son,u);
low[u]=MIN(low[u],low[son]);
if(low[son] > dfn[u]) //(u,son)是桥
{
num_bridge++;
init_bnode(); //缩点初始化
while(stack[--top] != son)
{
bnode[count_bnodeele++]=stack[top];
}
bnode[count_bnodeele]=stack[top]; for(int cn=;cn<=count_bnodeele;cn++) //缩点输出
printf("%c ",ALG->vlist[bnode[cn]].vertex);
printf("\n");
}
}
else if(son != parent)
{
low[u]=MIN(low[u],dfn[son]);
}
}
ptr=ptr->next;
}
}
while(top != ) //最后节点无法全部出栈,被自然分成一个连通分量【***此步必须要有***】
{
top--;
printf("%c ",ALG->vlist[stack[top]].vertex);
}
printf("\n");

点/边 双连通分量---Tarjan算法的更多相关文章

  1. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  2. HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)

    /** 题目大意: 给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想: 图的边双连通Tarjan算法+树形DP; 即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求 ...

  3. 浅谈 Tarjan 算法之强连通分量(危

    引子 果然老师们都只看标签拉题... 2020.8.19新初二的题集中出现了一道题目(现已除名),叫做Running In The Sky. OJ上叫绮丽的天空 发现需要处理环,然后通过一些神奇的渠道 ...

  4. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  5. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  6. Tarjan算法初探(3):求割点与桥以及双连通分量

    接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的 ...

  7. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

  8. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

     http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...

  9. [Tarjan系列] Tarjan算法求无向图的双连通分量

    这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...

随机推荐

  1. AWS系列之一 亚马逊云服务概述

    云计算经过这几年的发展,已经不再是是一个高大上的名词,而是已经应用到寻常百姓家的技术.每天如果你和互联网打交道,那么或多或少都会和云扯上关系.gmail.github.各种网盘.GAE.heroku等 ...

  2. MVVM架构~Knockoutjs系列之对象与对象组合

    返回目录 在面向对象的程序设计里,对象是核心,一切皆为对象,对象与对象之间的关系可以表现为继承和组合,而在Knockoutjs或者JS里,也存在着对象的概念,今天主要说一下JS里的对象及对象的组合. ...

  3. 知方可补不足~sqlserver中触发器的使用

    回到目录 触发器在过去的10年中,即存储过程和ado.net称霸江湖期间是那么的重要,而现在,trigger显得不是那么必要的,我们很少将复杂的业务写在SQL里,当然也会没有机会写到trigger里了 ...

  4. Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统

    今天大部分时间都在写业务代码,然后算是从无到有的配置了下spring与mybatis的集成. SpringMVC+Mybatis Web开发流程 配置数据源 在applicationContext.x ...

  5. java基础 数组14

    已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7}:把数组a与数组b 对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2]:最后输出数组b的元素.

  6. html_01之基础标签

    1.嵌套规则:①行内不能嵌套块:②p不能嵌套块:③非布局元素不要嵌套div: 2.标准属性:①id:定义元素唯一名称(a.布局时用:b.JS用):②title:鼠标移入时提示的文字:③class:定义 ...

  7. Android SDK 百度云盘分享链接

    SDK百度云盘地址: 链接: http://pan.baidu.com/s/1skSCplF 密码: drq4 使用说明: 这是Android开发所需的sdk,下载并解压后,将解压出的整个文件夹复制或 ...

  8. ScheduleThreadPoolExecutor的工作原理与使用示例

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. ScheduleExecutorService接口.ScheduledFuture ...

  9. ASP.NET 5中的那些K

    ASP.NET 5最大的变化是什么?首当其冲的就是多了很多K,K表示的是ASP.NET vNext的项目代号“Project K”,但很容易让人想到一个汉字——“坑”,希望K不要成为“坑”的缩写. K ...

  10. NodeJs连接Oracle数据库

    nodejs连接oracle数据库,各个平台的官方详情文档:https://github.com/oracle/node-oracledb/blob/master/INSTALL.md 我的nodej ...