UVA 796 Critical Links(模板题)(无向图求桥)
<题目链接>
题目大意:
无向连通图求桥,并将桥按顺序输出。
解题分析;
无向图求桥的模板题,下面用了kuangbin的模板。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 #include <vector> 7 using namespace std; 8 const int N = 1e4+10; 9 const int M = 1e5+10; 10 struct Edge{ 11 int to,next; 12 bool cut;//是否为桥的标记 13 }edge[M]; 14 int head[N],tot,n; 15 int low[N],dfn[N],Stack[N]; 16 int Index,top; 17 bool Instack[N],cut[N]; 18 int add_block[N];//删除一个点后增加的连通块 19 int bridge; 20 void init(){ 21 memset(head,-1,sizeof(head)); 22 memset(dfn,0,sizeof(dfn)); 23 memset(Instack,false,sizeof(Instack)); 24 memset(add_block,0,sizeof(add_block)); 25 memset(cut,false,sizeof(cut)); 26 Index=top=bridge=tot = 0; 27 } 28 void addedge(int u,int v){ 29 edge[tot].to = v;edge[tot].next = head[u];edge[tot].cut = false; 30 head[u] = tot++; 31 } 32 void Tarjan(int u,int pre){ 33 low[u] = dfn[u] = ++Index; 34 Stack[top++] = u; 35 Instack[u] = true; 36 int son = 0; 37 for(int i = head[u];i != -1;i = edge[i].next){ 38 int v = edge[i].to; 39 if(v == pre)continue; 40 if( !dfn[v] ){ 41 son++; 42 Tarjan(v,u); 43 if(low[u] > low[v])low[u] = low[v]; 44 if(low[v] > dfn[u]){ //一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足DFS(u)<low(v) 45 bridge++; 46 edge[i].cut = true; //正反两边都标记为桥 47 edge[i^1].cut = true; 48 } 49 if(u != pre && low[v] >= dfn[u]){ 50 cut[u] = true; //该点为割点 51 add_block[u]++; 52 } 53 } 54 else if( low[u] > dfn[v])low[u] = dfn[v]; 55 } 56 if(u == pre && son > 1)cut[u] = true; //若u为根,且分支数>1,则u割点 57 if(u == pre)add_block[u] = son - 1; 58 Instack[u] = false; 59 top--; 60 } 61 void solve(){ 62 for(int i = 1;i <= n;i++) 63 if( !dfn[i] ) 64 Tarjan(i,i); 65 printf("%d critical links\n",bridge); 66 67 vector<pair<int,int> >ans; /*-- 将桥按顺序输出 --*/ 68 for(int u = 1;u <= n;u++) 69 for(int i = head[u];i != -1;i = edge[i].next) 70 if(edge[i].cut && edge[i].to > u){ 71 ans.push_back(make_pair(u,edge[i].to)); 72 } 73 sort(ans.begin(),ans.end()); 74 for(int i = 0;i < ans.size();i++) 75 printf("%d - %d\n",ans[i].first-1,ans[i].second-1); 76 printf("\n"); 77 } 78 //处理重边 79 /*map<int,int>mapit; 80 inline bool isHash(int u,int v) 81 { 82 if(mapit[u*N+v])return true; 83 if(mapit[v*N+u])return true; 84 mapit[u*N+v] = mapit[v*N+u] = 1; 85 return false; 86 }*/ 87 int main(){ 88 while(scanf("%d",&n) == 1){ 89 init(); 90 int u,k,v; 91 //mapit.clear(); 92 for(int i = 1;i <= n;i++){ 93 scanf("%d (%d)",&u,&k); 94 u++; 95 //这样加边,要保证正边和反边是相邻的,建无向图 96 while(k--){ 97 scanf("%d",&v); 98 v++; 99 if(v <= u)continue; 100 //if(isHash(u,v))continue; 101 addedge(u,v); 102 addedge(v,u); 103 } 104 } 105 solve(); 106 } 107 return 0; 108 }
2018-10-18
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。