1 /********************************************
  2     Network(POJ 3694)
  3     http://poj.org/problem?id=3694
  4     桥入门题 + LCA(树中最小公共祖先)
  5     做这题必须要会用邻接表(做这题才学会),因为
  6     给的边有重边,用vector不好记录重边。
  7 
  8 ********************************************/
  9 
 10 #include<iostream>
 11 #include<algorithm>
 12 #include<cstring>
 13 #include<cstdio>
 14 using namespace std;
 15 
 16 const int M=100005;
 17 
 18 struct Eage                ///邻接表建图
 19 {
 20     int v;
 21     int next;
 22     int vs;
 23 };
 24 
 25 Eage eage[M*4];
 26 int low[M],dfn[M],father[M];  ///father[i]为i的父亲节点
 27 int flag[M],vs[M],head[M];    ///falg[i]为i和i的父亲节点的边
 28 int dfs_cut,ans,k;
 29 
 30 void Init()
 31 {
 32     memset(dfn,0,sizeof(dfn));
 33     memset(low,0,sizeof(low));
 34     memset(flag,0,sizeof(flag));
 35     memset(vs,0,sizeof(vs));
 36     memset(head,-1,sizeof(head));
 37     dfs_cut=ans=k=0;
 38 }
 39 
 40 void add(int u,int v)
 41 {
 42     eage[k].v=v;
 43     eage[k].vs=0;
 44     eage[k].next=head[u];
 45     head[u]=k++;
 46 }
 47 
 48 void dfs(int u)                     ///求桥
 49 {
 50     vs[u]=1;
 51     dfn[u]=low[u]=++dfs_cut;
 52     for (int i=head[u];i!=-1;i=eage[i].next)
 53     {
 54         if (!eage[i].vs)
 55         {
 56             eage[i].vs=eage[i^1].vs=1;
 57             int v=eage[i].v;
 58             if (!vs[v])
 59             {
 60                 father[v]=u;
 61                 dfs(v);
 62                 low[u]=min(low[u],low[v]);
 63                 if (dfn[u]<low[v])
 64                 {
 65                     ans++;
 66                     flag[v]=1;
 67                 }
 68             }
 69             else low[u]=min(low[u],dfn[v]);
 70         }
 71     }
 72 }
 73 
 74 void Lca(int u,int v)
 75 {
 76     if (dfn[u]<dfn[v])
 77     {
 78         u^=v;
 79         v^=u;
 80         u^=v;
 81     }
 82     while (dfn[u]>dfn[v])
 83     {
 84         if (flag[u]) ans--;
 85         flag[u]=0;
 86         u=father[u];
 87     }
 88     while (u!=v)
 89     {
 90         if (flag[v]) ans--;
 91         if (flag[u]) ans--;
 92         flag[u]=0;
 93         flag[v]=0;
 94         v=father[v];
 95         u=father[u];
 96     }
 97 }
 98 
 99 int main()
100 {
101   //  freopen("C://Users//Administrator//Desktop//in.txt","r",stdin);
102    // freopen("C://Users//Administrator//Desktop//out.txt","w",stdout);
103     int n,m,cut=0;
104     while (cin>>n>>m)
105     {
106         if (!n&&!m) return 0;
107         Init();
108         for (int i=1;i<=n;i++) father[i]=i;
109         int u,v;
110         while (m--)
111         {
112             cin>>u>>v;
113             add(u,v);
114             add(v,u);
115         }
116         dfs(1);
117         cout<<"Case "<<++cut<<":"<<endl;
118         int q;
119         cin>>q;
120         while (q--)
121         {
122             cin>>u>>v;
123             Lca(u,v);
124             cout<<ans<<endl;
125         }
126         cout<<endl;
127     }
128     return 0;
129 }

 

posted on 2016-04-08 19:39  pb2016  阅读(304)  评论(0编辑  收藏  举报