POJ3352 桥,边双连通分量,构造边双连通图
来源:互联网 发布:mac os 10.12镜像下载 编辑:程序博客网 时间:2024/05/16 07:07
虽然题目保证没有重边,但是代码适用于有重边的情况,另觉得网上流传的通过LOW值相等判断两点属于同一边双连通分量不对,可举出反例,本代码做法是利用tarjan求桥,删桥,缩点,(leaf+1)/2。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<stack>#include<fstream>using namespace std;#define maxv 1005struct Edge{ int T,Reverse; bool Mark; Edge() {} Edge(int t,int r) { T=t,Reverse=r; Mark=false; }};struct Bridge{ int Vertex,Index; Bridge() {} Bridge(int u,int i) { Vertex=u,Index=i; }};vector<Edge> G[maxv];vector<Bridge> BRI;int DFN[maxv],LOW[maxv],DEG[maxv],BEL[maxv];int IND,CNT;void Init(){ int i; for(i=0;i<maxv;++i) G[i].clear(); BRI.clear(); memset(DFN,0,sizeof(DFN)); memset(LOW,0,sizeof(LOW)); memset(DEG,0,sizeof(DEG)); memset(BEL,0,sizeof(BEL)); IND=0,CNT=0;}void Tarjan(int u){ DFN[u]=LOW[u]=++IND; int i,v; for(i=0;i<G[u].size();++i) { if(G[u][i].Mark) continue; v=G[u][i].T; G[u][i].Mark=true; G[v][G[u][i].Reverse].Mark=true; if(DFN[v]==0) { Tarjan(v); LOW[u]=min(LOW[u],LOW[v]); if(DFN[u]<LOW[v]) BRI.push_back(Bridge(u,i)); } else LOW[u]=min(LOW[u],DFN[v]); }}void Part(int u){ BEL[u]=CNT; int i,v; for(i=0;i<G[u].size();++i) { if(G[u][i].Mark==false) continue; v=G[u][i].T; G[u][i].Mark=false; G[v][G[u][i].Reverse].Mark=false; if(BEL[v]!=0) continue; Part(v); }}int Solve(int n){ int i,u,v,ind,leaf=0; Tarjan(1); //因为题目已经保证一次深搜即可遍历所有顶点了// cout<<"Part 1 end"<<endl; 已经求出所有的桥 for(i=0;i<BRI.size();++i) { u=BRI[i].Vertex,ind=BRI[i].Index; G[u][ind].Mark=false; v=G[u][ind].T; ind=G[u][ind].Reverse; G[v][ind].Mark=false; }// cout<<"Part 2 end"<<endl; 通过标记,删去桥 for(i=1;i<=n;++i) if(BEL[i]==0) { CNT++; Part(i); }// cout<<"Part 3 end"<<endl; 求出边双连通分量 for(i=0;i<BRI.size();++i) { u=BRI[i].Vertex,ind=BRI[i].Index; v=G[u][ind].T; DEG[BEL[u]]++; DEG[BEL[v]]++; }// cout<<"Part 4 end"<<endl; //求度数 无相图任意两个双连通分量只能有一条边相连,不能有重边,否则就可以变成一个双连通分量 //因此可以通过枚举桥来求度数 for(i=1;i<=CNT;++i) if(DEG[i]==1) leaf++;// cout<<"Part 5 end"<<endl; return (leaf+1)/2;} int main(){ int n,m,u,v,tmp,r1,r2;// ifstream fin("data.txt");// fin>>n>>m; scanf("%d %d",&n,&m); Init(); while(m--) {// fin>>u>>v; scanf("%d %d",&u,&v); r1=G[v].size(); r2=G[u].size(); G[u].push_back(Edge(v,r1)); G[v].push_back(Edge(u,r2)); } cout<<Solve(n)<<endl;// system("pause"); return 0;}
- POJ3352 桥,边双连通分量,构造边双连通图
- poj3352 Road Construction(边双连通分量)
- poj3352[无向图双连通分量]
- POJ3352.Road Construction——边-双连通分量
- poj3352 Road Construction 边双连通分量tarjan算法
- 双连通分量 poj3352 poj2186
- 边双连通分量
- POJ3352 Road Construction 双连通分量和桥 tarjan
- POJ3352 Road Construction (双连通分量)
- 点-双连通分量&边-双连通分量复习笔记
- 边双连通分量模版
- HDU4738【边双连通分量】
- 边双连通分量模板
- 【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题
- POJ 3352 边的双连通分量
- HDU 3390 Railway 边双连通分量
- POJ3177_Redundant_Paths_边双连通分量_tarjan
- hdu 2242(边双连通分量)
- PHP笔记
- centos 命令补全
- J2EE flex框架
- vs的【warning C4996:'fopen': This function or variable may be unsafe】解决方案
- POJ 1113(Wall-Quickhull)
- POJ3352 桥,边双连通分量,构造边双连通图
- poj - 2142 - The Balance
- Google Play services SDK的安装
- SQL Prompt:SQL智能提示功能的SQL Server和VS插件
- Linux下autoconf和automake使用
- 小游戏系列算法之五广度优先搜索,双向广搜,八数码,华容道
- 挖掘机效果(SHADER无阴影)2013.2.8
- Listview异步加载图片之优化篇(有图有码有解释)
- JS学习 面向对象 2