运用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. Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密

    前不久,微信的企业号使用了强制的消息加密方式,随后公众号也加入了可选的消息加密选项.目前企业号和公众号的加密方式是一致的(格式会有少许差别). 加密设置 进入公众号后台的“开发者中心”,我们可以看到U ...

  2. js 把url参数转对象

    //注意url中要含? function getParameterByName(name, url) {            if (!url) {                url = win ...

  3. Java中static的理解

    static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...

  4. Atitit 发帖机系列(6) USRQBN2201 setup spec安装程序的实现规范与标准化解决方案

    Atitit 发帖机系列(6) USRQBN2201 setup spec安装程序的实现规范与标准化解决方案 安装主要解决一个问题,就是resin的内容启动路径以及端口..这里是使用的端口8077 主 ...

  5. Java EE开发平台随手记6——Mybatis扩展4

    这篇博客中来说一下对Mybatis动态代理接口方式的扩展,对于Mybatis动态代理接口不熟悉的朋友,可以参考前一篇博客,或者研读Mybatis源码. 扩展11:动态代理接口扩展 我们知道,真正在My ...

  6. DELPHI支付宝支付代码

    真实业务场景的考虑 按照支付宝或者微信支付的开发手册的说法,一个标准的客户端接入支付业务模型应该是这样的,我忽略时序图,只用文字描述: 用户登录客户端,选择商品,然后点击客户端支付. 客户端收集商品信 ...

  7. .NET面试题解析(03)-string与字符串操作

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 字符串可以说是C#开发中最常用的类型了,也是对系统性能影响很关键的类型,熟练掌握字符串的操作非常重要. 常 ...

  8. WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Pro ...

  9. RAC Concept

    1. RAC的高可用性 RAC的高可用性主要包含以下几点: 1> 实现节点间的负载均衡. 2> 实现失败切换的功能. 3> 通过Service组件来控制客户端的访问路径. 4> ...

  10. tomcat server容器解读

    1. server的实例类为:org.apache.catalina.core.StandardServer为顶层容器. 2.二级容器GlobalNamingResources,设置认证用户信息. & ...