#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 100010
#define maxm 200010
using namespace std;
struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){ to=_to,next=_next; }
}e[maxm<<1];
int head[maxn],k;
int dep[maxn],pre[maxn],fa[maxn];
int dfn[maxn],low[maxn],tot,stack[maxn],top;
int uu[maxm],vv[maxm];
int n,m,t,ans;
inline void init(){
for(register int i=0;i<=n;i++) head[i]=-1,dep[i]=dfn[i]=0;
k=top=ans=tot=0;
}
inline void add(const int &u,const int &v){ e[k]=edge(v,head[u]),head[u]=k++; }
void tarjan_dcc(int u,int pre){
if(dfn[u]) return;
dfn[u]=low[u]=++tot,stack[++top]=u;
bool flag=true;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==pre&&flag) { flag=false; continue; }
tarjan_dcc(v,u),low[u]=min(low[u],low[v]);
}
if(dfn[u]==low[u]){
while(stack[top]!=u) low[stack[top--]]=low[u];
top--;
}
}
inline void rebuild(){
for(register int i=0;i<=n;i++) head[i]=-1; k=0;
for(register int i=0;i<m;i++){
int u=low[uu[i]],v=low[vv[i]];
if(u!=v) add(u,v),add(v,u);
}
}
void dfs(int u,int father,int deep){
dep[u]=deep,pre[u]=u;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v!=father) dfs(v,u,deep+1),fa[v]=u,ans++;
}
}
int get(int x){
if(x!=pre[x]) pre[x]=get(pre[x]);
return pre[x];
}
inline void getlca(int u,int v){
u=get(u),v=get(v),top=0;
while(u!=v){
if(dep[u]>dep[v]) stack[++top]=u,u=get(fa[u]);
else stack[++top]=v,v=get(fa[v]);
ans--;
}
while(top) pre[stack[top--]]=u;
}
int main(){
int T=0;
while(~scanf("%d %d",&n,&m),n+m){
init();
for(register int i=0;i<m;i++){
scanf("%d %d",&uu[i],&vv[i]);
add(uu[i],vv[i]),add(vv[i],uu[i]);
}
tarjan_dcc(1,-1),rebuild();
dfs(low[1],-1,1);
scanf("%d",&t);
printf("Case %d:\n",++T);
while(t--){
int u,v; scanf("%d %d",&u,&v);
getlca(low[u],low[v]);
printf("%d\n",ans);
}
printf("\n");
}
return 0;
}
原文:https://www.cnblogs.com/akura/p/10976147.html