POJ3694 Network 割边 LCA

来源:互联网 发布:空调换热器设计软件 编辑:程序博客网 时间:2024/04/25 14:19

题意:有n台电脑,他们之间有m条线使得它们能够通讯联网,有些网线是重要的,如果出故障会使得部分电脑无法连通。称这种出故障能造成无法连通的线为桥,现在为了测试,在原来的基础基础上新加Q条网线,每加一条判断,判断网络中有多少桥。

也就是求无向图割边(桥)的数量。当然不能没加一条,就用tarjin算法来求割边。

#include<iostream>#include<cstdio>#include<vector>#include<cstring>#define Min(a,b) a<b?a:busing namespace std;const int maxn = 100001;vector<int> g[maxn];int dfn[maxn],low[maxn];int bi[maxn],fa[maxn];int time,cnt;void tarjin(int u,int pre){dfn[u]=low[u]=++time;for(int i=0;i<g[u].size();i++){int v = g[u][i];if(!dfn[v]){tarjin(v,u);fa[v]=u;low[u]=Min(low[u],low[v]);if(low[v]>dfn[u]){bi[v]=1;cnt++;}}else if(v!=pre)low[u]=Min(low[u],low[v]);}}int judge(int u,int v){int cnt1=0;while(dfn[u]>dfn[v]){if(bi[u]){cnt1++;bi[u]=0;}u=fa[u];}while(dfn[u]<dfn[v]){if(bi[v]){cnt1++;bi[v]=0;}v=fa[v];}while(u!=v){if(bi[u]){cnt1++;bi[u]=0;}if(bi[v]){cnt1++;bi[v]=0;}u=fa[u];v=fa[v];}return cnt1;}int main(){int n,m,u,v,Q,kcase=1;while(scanf("%d%d",&n,&m)&&(n+m)){for(int i=1;i<=n;i++)g[i].clear();for(int i=0;i<m;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}time=cnt=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(bi,0,sizeof(bi));memset(fa,0,sizeof(fa));for(int i=1;i<=n;i++){tarjin(1,-1);}scanf("%d",&Q);printf("Case %d:\n",kcase++);for(int i=0;i<Q;i++){scanf("%d%d",&u,&v);cnt-=judge(u,v);printf("%d\n",cnt);}printf("\n");}}

0 0
原创粉丝点击