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
",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
",ans[i].first-1,ans[i].second-1);
 76     printf("
");
 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

原文地址:https://www.cnblogs.com/00isok/p/9808085.html