历时好几天,终于完工了!

支持无向图四种功能:
1.割点的求解

2.割边的求解

3.点双连通分量的求解

4.边双连通分量的求解

全部支持重边!!!!全部支持重边!!!!全部支持重边!!!!

测试数据:

10 11
1 5
3 5
4 5
2 4
2 3
4 6
6 8
6 7
7 8
8 10
8 9

/*
By:ZUFE_ZZT
该模板经过多次修改与研究,修正了很多错误,增加了很多功能。
无向图,完全支持重边!!完全支持重边!!
【功能如下】
1.求割点的编号,以及去掉割点有多少连通分量
2.求点双连通分量
3.求割边的编号
4.求边双连通分量
*/ #include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std; const int maxn=+; //结点数量
const int Maxn=*+; //边的数量
int low[maxn];
int dfn[maxn];
int U[maxn],V[maxn];//存初始边
int flag[maxn];//判断第i条边是不是割边
int iscut[maxn];//判断i结点是不是割点,去掉之后有几个连通分量
struct Edge
{
int from,to,id,ans;//ans为1,表示这条边是割边
} edge[Maxn];
vector<int>G[maxn];//邻接表
int N,M;//N个结点,M条边
int tmpdfn;//时间戳
int tot;
int son;
int Start,End; //以下是输出点双连通分量用的
int top;
struct Printf_Egde
{
int u,v,id;
void output()
{printf("(%d,%d) ",u,v);}
};
Printf_Egde Stack[Maxn];
int Flag[Maxn]; int TxT[maxn];//求边双连通分量用的 void init()
{
for(int i=; i<maxn; i++) G[i].clear();
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(iscut,,sizeof(iscut));
memset(Flag,,sizeof(Flag));
memset(flag,,sizeof(flag));
memset(TxT,,sizeof(TxT));
low[]=dfn[]=;
tmpdfn=;
tot=;
son=;
top=-;
} void AddEdge(int u,int v)
{
edge[tot].from=u;
edge[tot].to=v;
edge[tot].id=tot;
edge[tot].ans=;
G[u].push_back(tot);
tot++; edge[tot].from=v;
edge[tot].to=u;
edge[tot].id=tot;
edge[tot].ans=;
G[v].push_back(tot);
tot++;
} int Tarjan(int u,int id)
{
tmpdfn++;
int lowu=dfn[u]=tmpdfn;
for(int i=; i<G[u].size(); i++)
{
int B=G[u][i]; Printf_Egde t;
if(!Flag[edge[B].id/])//没有入过栈
{
Flag[edge[B].id/]=;
t.u=u;
t.v=edge[B].to;
t.id=edge[B].id/;
Stack[++top]=t;
}
if(!dfn[edge[B].to])
{
int lowv=Tarjan(edge[B].to,edge[B].id);
lowu=min(lowu,lowv);
if(lowv>=dfn[u])
{
if(u!=) iscut[u]++;
if(u==) son++; //输出点双连通分量
printf("点双连通分量:");
while()
{
if(top==-) break;
Printf_Egde t1;
t1=Stack[top];
t1.output();
top--;
if(t1.id==t.id) break;
}
printf("\n"); //判断是不是割边
if(lowv>dfn[u])
edge[B].ans=;
}
}
else if(dfn[edge[B].to])
{
if(edge[B].id/==id/) continue;
lowu=min(lowu,dfn[edge[B].to]);
}
} low[u]=lowu;
return lowu;
} void Display_Cutting_edge()
{
for(int i=; i<*M; i++)
if(edge[i].ans)
printf("第%d条边是割边:(%d,%d)\n",edge[i].id/,edge[i].from,edge[i].to); } void Display_Cutting_point()
{
if(son>) iscut[]=son-;
for(int i=Start;i<=End;i++)
if(iscut[i])
printf("编号为%d的结点是割点,删除后有%d个连通分量\n",i,iscut[i]+);
} void Dfs(int x,int y)
{
int XZ=;
for(int i=;i<G[x].size();i++)
{
int B=G[x][i];
if(!flag[edge[B].id/])
{
XZ=;
flag[edge[B].id/]=;
TxT[edge[B].to]=;
printf("(%d,%d) ",edge[B].from,edge[B].to);
Dfs(edge[B].to,y+);
}
}
if(!XZ&&!y) printf("(%d) ",x);
} void Slove()
{
//把桥都标为1
for(int i=; i<*M; i++)
if(edge[i].ans)
flag[edge[i].id/]=; for(int i=Start;i<=End;i++)
{
if(!TxT[i])
{
TxT[i]=;
printf("边双连通分量:");
Dfs(i,);
printf("\n");
}
}
} int main()
{
scanf("%d%d",&N,&M);
init();
for(int i=; i<M; i++)
{
scanf("%d%d",&U[i],&V[i]);
AddEdge(U[i],V[i]);
} //设置结点编号的起点和终点
Start=;
End=N; Tarjan(,-); //割点的输出
Display_Cutting_point(); //割边的输出
Display_Cutting_edge(); //点双连通分量在Tarjan过程中已经输出了 //求边双连通分量,并输出
Slove(); return ;
}

Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板的更多相关文章

  1. TarJan 算法求解有向连通图强连通分量

    [有向图强连通分量] 在有向图G中,如果两个 顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的 ...

  2. Tarjan算法:求解无向连通图图的割点(关节点)与桥(割边)

    1. 割点与连通度 在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点(Articulation Point).一个没有关节点的 ...

  3. 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)

    poj2117 Electricity Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3603   Accepted: 12 ...

  4. tarjan算法--求解无向图的割点和桥

    1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥 也就是说 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥 2.割点:无向连通图中,如 ...

  5. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

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

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

  7. 有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告

    题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法 有向图强连通分支的Tarjan算法伪代码如下:void Tarjan(u) {dfn[u]=low[u]=++index//进行DF ...

  8. 20行代码实现,使用Tarjan算法求解强连通分量

    今天是算法数据结构专题的第36篇文章,我们一起来继续聊聊强连通分量分解的算法. 在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实 ...

  9. POJ1523:SPF(无向连通图求割点)

    题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...

随机推荐

  1. for i in xrange(0,5)使用过程中遇到的问题

    文件中共有4行内容. fd = open("C:\Users\william\Desktop\dup_file - Copy (2).txt")for i in xrange(0, ...

  2. 101个Linq例子(40-60)

    GroupBy - Simple 2 public void Linq41() { string[] words = { "blueberry", "chimpanzee ...

  3. unsupported major.minor version 52.0,错误

    Make sure that all the classes needed by the application have been compiled with a compatible java v ...

  4. python自动化Traceback (most recent call last):报错

    今天使用python.然而遇见了Traceback (most recent call last):的报错.抓狂的一笔.有说path写错的,有说是...网上查到的资料也是很少.后来突然发现,页面上我暂 ...

  5. Scope Directive

    ---------------------------Scope-------------------------------- https://docs.angularjs.org/guide/sc ...

  6. JAVA多态问题总结(课堂总结)

    面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点.多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发 ...

  7. win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误

    1 确保IPsec Policy Agent服务已启动 2 确保路由和远程访问(Routing and Remote Access)和远程访问连接管理器服务(Remote Access Connect ...

  8. CentOS 下网络报错 Device eth0 does not seem to be present

    在执行network服务重启后,出现Device eth0 does not seem to be present  问题,主要是因为系统之前有多个网卡配置,和配置文件不匹配造成的. 解决这种问题,思 ...

  9. JAVA String 工具类

    java StringUtil 字符串工具类 import java.util.ArrayList; import java.util.LinkedHashSet; import java.util. ...

  10. post请求和get请求

    get请求在链接后面带参数,容易出现乱码,是坑(慎用),有固定的长度 一般的用的就是post方式 <form action="<%=basePath%>upload&quo ...