3694

1 /*
2 求割边,暴力LCA
3 */
4
5 // include file
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstring>
9 #include <cmath>
10 #include <cctype>
11 #include <ctime>
12
13 #include <iostream>
14 #include <sstream>
15 #include <fstream>
16 #include <iomanip>
17 #include <bitset>
18
19 #include <algorithm>
20 #include <string>
21 #include <vector>
22 #include <queue>
23 #include <set>
24 #include <list>
25 #include <functional>
26
27 using namespace std;
28
29 // typedef
30 typedef long long LL;
31 typedef unsigned long long ULL;
32 typedef __int64 Bint;
33
34 //
35 #define read freopen("in.txt","r",stdin)
36 #define write freopen("out.txt","w",stdout)
37 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
38 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
39 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
40 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
41 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
42 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
43 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
44
45 #define FF(i,a) for(int i=0;i<(a);i++)
46 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
47
48 #define Z(a) (a<<1)
49 #define Y(a) (a>>1)
50
51 const double eps = 1e-6;
52 const double INFf = 1e10;
53 const int INFi = 1000000000;
54 const double Pi = acos(-1.0);
55
56 template<class T> inline T sqr(T a){return a*a;}
57 template<class T> inline T TMAX(T x,T y)
58 {
59 if(x>y) return x;
60 return y;
61 }
62 template<class T> inline T TMIN(T x,T y)
63 {
64 if(x<y) return x;
65 return y;
66 }
67 template<class T> inline void SWAP(T &x,T &y)
68 {
69 T t = x;
70 x = y;
71 y = t;
72 }
73 template<class T> inline T MMAX(T x,T y,T z)
74 {
75 return TMAX(TMAX(x,y),z);
76 }
77
78
79 // code begin
80
81 #define MAXN 100010
82 #define MAXM 400010
83
84 int N,M,Q;
85 struct node1
86 {
87 int e;
88 int next;
89 };
90 struct node2
91 {
92 int next;
93 };
94 node1 mem[MAXM];
95 node2 G[MAXN];
96
97 int dfn[MAXN];
98 int low[MAXN];
99 int used[MAXN];
100 int father[MAXN];
101 int isbridge[MAXN];
102 int bnum;
103
104 void Add_edge(int dx,int a,int b)
105 {
106 mem[dx].e = b;
107 mem[dx].next = G[a].next;
108 G[a].next = dx;
109 }
110
111 void BCC_tarjan(int i,int fa,int bh)
112 {
113 dfn[i] = bh;
114 low[i] = bh;
115 used[i] = true;
116
117 int dx = G[i].next;
118 while(dx!=-1)
119 {
120 int v = mem[dx].e;
121 if(!used[v])
122 {
123 father[v] = i;
124 BCC_tarjan(v,i,bh+1);
125 low[i] = TMIN(low[i],low[v]);
126 if(low[v]>dfn[i])
127 {//割边
128 isbridge[v] = true;
129 bnum ++;
130 }
131 }
132 else if(v!=fa)
133 {
134 low[i] = TMIN(low[i],dfn[v]);
135 }
136 dx = mem[dx].next;
137 }
138 }
139
140 void LCA(int a,int b)
141 {
142 if(dfn[a]<dfn[b]) SWAP(a,b);
143 while(dfn[a]>dfn[b])
144 {
145 if(isbridge[a])
146 {
147 isbridge[a]=false;
148 bnum--;
149 }
150 a = father[a];
151 }
152 while(a!=b)
153 {
154 if(isbridge[a]){
155 isbridge[a] = false;
156 bnum--;
157 }
158 if(isbridge[b]){
159 isbridge[b] = false;
160 bnum--;
161 }
162 a = father[a];
163 b = father[b];
164 }
165 }
166
167 int main()
168 {
169 read;
170 write;
171 int dx,a,b,cas=1;
172 while(scanf("%d %d",&N,&M)!=-1)
173 {
174 if(N+M==0) break;
175 FORi(1,N+1,1)
176 G[i].next=-1;
177 dx = 0;
178 FORi(0,M,1)
179 {
180 scanf("%d %d",&a,&b);
181 Add_edge(dx++,a,b);
182 Add_edge(dx++,b,a);
183 }
184
185 memset(dfn,0,sizeof(dfn));
186 memset(low,0,sizeof(low));
187 memset(used,0,sizeof(used));
188 memset(father,0,sizeof(father));
189 memset(isbridge,0,sizeof(isbridge));
190 bnum = 0;
191 FORi(1,N+1,1)
192 {
193 if(!used[i])
194 {
195 father[i] = i;
196 BCC_tarjan(i,-1,1);
197 }
198 }
199 printf("Case %d:\n",cas++);
200 scanf("%d",&Q);
201 while(Q--)
202 {
203 scanf("%d %d",&a,&b);
204 LCA(a,b);
205 printf("%d\n",bnum);
206 }
207 printf("\n");
208 }
209 return 0;
210 }
posted @ 2011-03-14 14:56  AC2012  阅读(706)  评论(0编辑  收藏  举报