首页 > 代码库 > HDU 2460 Network(桥+LCA)

HDU 2460 Network(桥+LCA)

http://acm.hdu.edu.cn/showproblem.php?pid=2460

题意:
给出图,求每次增加一条边后图中桥的数量。

 

思路:

先用tarjan算法找出图中所有的桥,如果lowv>pre[u],那么u—v就是桥,此时可以标记一下v。

之后就是利用LCA,找到两个节点的公共祖先,在这条路径上的桥就不再是桥了。(此时就相当于这些桥组成的树,可以在脑海中缩点)

  1 #include<iostream>  2 #include<algorithm>  3 #include<cstring>  4 #include<cstdio>  5 #include<sstream>  6 #include<vector>  7 #include<stack>  8 #include<queue>  9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn=100000+5; 17  18 int n, m; 19 int tot; 20 int cnt; 21 int head[maxn]; 22 int dfs_clock; 23 int pre[maxn]; 24 int low[maxn]; 25 int isbridge[maxn]; 26 int p[maxn]; 27  28 struct node 29 { 30     int v; 31     int next; 32 }e[400000+5]; 33  34 void addEdge(int u, int v) 35 { 36     e[tot].v=v; 37     e[tot].next=head[u]; 38     head[u]=tot++; 39 } 40  41 void init() 42 { 43     cnt=0; 44     dfs_clock=0; 45     memset(pre,0,sizeof(pre)); 46     memset(isbridge,0,sizeof(isbridge)); 47     for(int i=1;i<=n;i++)  p[i]=i; 48 } 49  50 int dfs(int u, int fa) 51 { 52     int lowu=pre[u]=++dfs_clock; 53     for(int i=head[u];i!=-1;i=e[i].next) 54     { 55         int v=e[i].v; 56         if(!pre[v]) 57         { 58             p[v]=u; 59             int lowv=dfs(v,u); 60             lowu=min(lowu,lowv); 61             if(lowv>pre[u])   {cnt++;isbridge[v]=1;} 62         } 63         else if(pre[v]<pre[u] && v!=fa) 64             lowu=min(lowu,pre[v]); 65     } 66     return low[u]=lowu; 67 } 68  69 int LCA(int u, int v) 70 { 71     while(low[u]>low[v]) 72     { 73         if(isbridge[u])  {cnt--;isbridge[u]=0;} 74         u=p[u]; 75     } 76     while(low[v]>low[u]) 77     { 78         if(isbridge[v])  {cnt--;isbridge[v]=0;} 79         v=p[v]; 80     } 81     while(u!=v) 82     { 83         if(isbridge[u])  {cnt--;isbridge[u]=0;} 84         if(isbridge[v])  {cnt--;isbridge[v]=0;} 85         u=p[u]; 86         v=p[v]; 87     } 88 } 89  90 int main() 91 { 92     //freopen("in.txt","r",stdin); 93     int kase=0; 94     while(~scanf("%d%d",&n,&m)) 95     { 96         if(n==0 && m==0)  break; 97         tot=0; 98         memset(head,-1,sizeof(head)); 99         while(m--)100         {101             int u,v;102             scanf("%d%d",&u,&v);103             addEdge(u,v);104             addEdge(v,u);105         }106         init();107         dfs(1,-1);108         int q;109         scanf("%d",&q);110         printf("Case %d:\n",++kase);111         while(q--)112         {113             int u,v;114             scanf("%d%d",&u,&v);115             LCA(u,v);116             printf("%d\n",cnt);117         }118         printf("\n");119     }120     return 0;121 }

 

HDU 2460 Network(桥+LCA)