#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;
// #define int long long
const int MAXN=5e5+10;
const int N=5e5+10;
struct Edge{
int to,nxt;
bool cut;
int val;
}edge[MAXN];
int head[MAXN],tot=0;
int low[MAXN],dfn[MAXN],sta[MAXN];
int Index,top;
bool instack[MAXN];
int belong[MAXN];
int bridge,block;
void addedge(int u,int v,int w){
edge[tot].to=v;edge[tot].nxt=head[u];
edge[tot].cut=false;edge[tot].val=w;
head[u]=tot++;
}
int num=0;
void tarjan(int u,int pre){
int v;
low[u]=dfn[u]=++Index;
sta[top++]=u;
instack[u]=true;
int precnt=0;
for(int i=head[u];~i;i=edge[i].nxt){
v=edge[i].to;
if(!dfn[v]){
tarjan(v,u);
num++;
if(low[u]>low[v]) low[u]=low[v];
if(low[v]>dfn[u]){
bridge++;
edge[i].cut=true;
}
}else if(instack[v]&&low[u]>dfn[v]){
low[u]=dfn[v];
}
}
if(low[u]==dfn[u]){
block++;
do{
v=sta[--top];
instack[v]=false;
belong[v]=block;
}while(v!=u);
}
}
int n,m,Q;
struct LCA{
struct node{
int nxt,to;
}d[N];int head[N],tot;
void add(int a,int b){
d[++tot].nxt=head[a];
d[tot].to=b;
head[a]=tot;
}
int fa[N][26],depth[N];
int n,q;
void dfs(int x,int f){
depth[x]=depth[f]+1;
fa[x][0]=f;
for(int i=1;i<26;i++){fa[x][i]=fa[fa[x][i-1]][i-1];}
for(int i=head[x];i;i=d[i].nxt){
int v=d[i].to;if(v==f) continue;
dfs(v,x);
}
}
int query(int a,int b){
if(depth[a]<depth[b]) swap(a,b);
for(int i=25;i>=0;i--){
if(depth[fa[a][i]]>=depth[b]) a=fa[a][i];
}
if(a==b) return a;
for(int i=25;i>=0;i--){
if(fa[a][i]!=fa[b][i]){
a=fa[a][i];b=fa[b][i];
}
}
return fa[a][0];
}
void init(){
memset(fa,0,sizeof fa);
memset(depth,0,sizeof depth);
dfs(1,0);
}
}lca;
void init(){
tot=0;memset(head,-1,sizeof head);
lca.tot=1;memset(lca.head,0,sizeof lca.head);
}
pair<int,int> pa[MAXN];
struct node3{
int fa[N];
void init(){
for(int i=1;i<=n;i++) fa[i]=i;
}
int find(int x){
if(fa[x]==x) return x;
else return fa[x]=find(fa[x]);
}
}hh;
int cas=0,viss[MAXN];
void solve(int n){
memset(viss,0,sizeof viss);
memset(dfn,0,sizeof dfn);
memset(instack,false,sizeof instack);
Index=top=bridge=block=0;
int fl=0;
for(int i=1;i<=n;i++){
if(dfn[i]==0){
tarjan(i,i);
}
}
for(int i=1;i<=m;i++){
int a=pa[i].first,b=pa[i].second;
if(belong[a]!=belong[b]){
lca.add(belong[a],belong[b]);
lca.add(belong[b],belong[a]);
}
}
lca.init();hh.init();
scanf("%d",&Q);
printf("Case %d:\n",++cas);
int sum=block-1;
while(Q--){
int l,r;scanf("%d%d",&l,&r);
int a=belong[l],b=belong[r];
int lcapos=lca.query(a,b);
int now=a;
while(now!=lcapos){
if(viss[now]==0) sum--;
viss[now]=1;
now=lca.fa[now][0];
}
now=b;
while(now!=lcapos){
if(viss[now]==0) sum--;
viss[now]=1;
now=lca.fa[now][0];
}
cout<<sum<<endl;
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF&&n+m){
init();
for(int i=1;i<=m;i++){
int a,b,c;scanf("%d%d",&a,&b);
addedge(a,b,1);
pa[i].first=a;pa[i].second=b;
}
solve(n);
cout<<endl;
}
}
poj3694 Network(连通图+lca+毒瘤) 待补
最新推荐文章于 2022-03-14 18:13:28 发布