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

支持无向图四种功能:
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. bfs或者dfs Good Bye 2016 D

    http://codeforces.com/contest/750/problem/D 题目大意: 放鞭炮,鞭炮会爆炸n次,每次只会往目前前进方向的左上和右上放出他的子鞭炮.问,最后能有多少格子被覆盖 ...

  2. WEB服务器:Apache、Tomcat、JBoss、WebLogic、Websphere、IIS的区别与关系

    1)Apache  免费,世界使用排名第一的Web服务器.它可以运行在几乎所有广泛使用的计算机平台上.Apache的特点是简单.速度快.性能稳定,并可做代理服务器来使用.Apache是以进程为基础的结 ...

  3. Debian系Linux的dpkg命令

    dpkg "是"Debian Packager "的简写.为 "Debian" 专门开发的套件管理系统,方便软件的安装.更新及移除.所有源自" ...

  4. hdfs格式化hadoop namenode -format错误

    在对HDFS格式化,执行hadoop namenode -format命令时,出现未知的主机名的问题,异常信息如下所示: [shirdrn@localhost bin]$ hadoop namenod ...

  5. JQery之Ajax

    $.ajax({ url:'/comm/test1.php', type:'POST', //GET async:true, //或false,是否异步 data:{ name:'yang',age: ...

  6. Windows后渗透

    My 命令行下收集主机信息 使用wmic识别安装到系统中的补丁情况: wmic qfe get description,installedOn 识别正在运行的服务: sc query type= se ...

  7. visual studio2013 apache cordova基于web的跨平台应用

    目前在研究微软的visual studio 2013开发跨平台的android.ios.windows phone.当然是基于html javascript css的web跨平台app. 在visua ...

  8. 浙江大学 pat 1006题解

    1006. Sign In and Sign Out (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  9. sublime eslint setup

    [Setting Up ESLint] https://www.youtube.com/watch?v=QUK4hMoYv_c

  10. 如何在网页标题栏title加入logo图标?

    打开某一个网页会在浏览器的标签栏处显示该网页的标题和图标,当网页被添加到收藏夹或者书签中时也会出现网页的图标,怎么在网页title左边显示网页的logo图标呢? 方法一(被动式): 制作一个ico格式 ...