- 无向图的必经点问题
- 注意栈中n1和y未必相邻,须以y作为终止标记
#include <bits/stdc++.h>
using namespace std;
int to[200005],nx[200005],h[10005],tot,id[10005],tag[10005],e[200005];
int dfn[10005],low[10005];
vector<int>a[20005];
vector<int>dcc[10005];
int cnt,num,root;
bool cut[10005];
stack<int>s;
void add(int u,int v)
{
tot++;
to[tot]=v;
nx[tot]=h[u];
h[u]=tot;
}
void tarjan(int n1)
{
dfn[n1]=low[n1]=++tot;
s.push(n1);
if(n1==root&&h[n1]==0)
{
cnt++;
dcc[cnt].push_back(n1);
}
int tmp=0;
for(int i=h[n1];i;i=nx[i])
{
int y=to[i];
if(!dfn[y])
{
tarjan(y);
low[n1]=min(low[n1],low[y]);
if(dfn[n1]<=low[y])
{
tmp++;
if(root!=n1||tmp>=2)
{
cut[n1]=true;
}
cnt++;
while(s.top()!=y)
{
dcc[cnt].push_back(s.top());
s.pop();
}
dcc[cnt].push_back(y);
s.pop();
dcc[cnt].push_back(n1);
}
}
else
{
low[n1]=min(low[n1],dfn[y]);
}
}
}
int d[20005],f[20005][15],dis[20005];
void dfs(int n1)
{
for(int i=0;i<a[n1].size();i++)
{
if(a[n1][i]!=f[n1][0])
{
f[a[n1][i]][0]=n1;
d[a[n1][i]]=d[n1]+1;
dis[a[n1][i]]=dis[n1]+(n1>cnt);
dfs(a[n1][i]);
}
}
}
void pre()
{
for(int j=1;j<=14;j++)
{
for(int i=1;i<=num;i++)
{
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int lca(int u,int v)
{
if(d[u]<d[v])
{
swap(u,v);
}
for(int i=14;i>=0;i--)
{
if(d[v]<=d[f[u][i]])
{
u=f[u][i];
}
}
if(u==v)
{
return u;
}
for(int i=14;i>=0;i--)
{
if(f[u][i]!=f[v][i])
{
u=f[u][i];
v=f[v][i];
}
}
return f[u][0];
}
int dist(int u,int v)
{
int l=lca(u,v);
return dis[u]+dis[v]-2*dis[l]-(l>cnt);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin>>n>>m;
while(!(n==0&&m==0))
{
tot=1;
for(int i=1;i<=n;i++)
{
h[i]=tag[i]=0;
dcc[i].clear();
dfn[i]=0;
cut[i]=false;
}
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
tot=cnt=0;
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
root=i;
tarjan(i);
while(s.size())
{
s.pop();
}
}
}
num=cnt;
for(int i=1;i<=n;i++)
{
if(cut[i])
{
num++;
id[i]=num;
}
}
for(int i=1;i<=num;i++)
{
a[i].clear();
f[i][0]=0;
d[i]=0;
}
for(int i=1;i<=cnt;i++)
{
for(int j=0;j<dcc[i].size();j++)
{
tag[dcc[i][j]]=i;
}
for(int j=0;j<dcc[i].size();j++)
{
int x=dcc[i][j];
for(int k=h[x];k;k=nx[k])
{
if(tag[to[k]]==tag[x])
{
e[k]=i;
}
}
}
for(int j=0;j<dcc[i].size();j++)
{
if(cut[dcc[i][j]])
{
a[i].push_back(id[dcc[i][j]]);
a[id[dcc[i][j]]].push_back(i);
}
else
{
id[dcc[i][j]]=i;
}
}
}
for(int i=1;i<=num;i++)
{
if(!d[i])
{
d[i]=1;
dis[i]=0;
dfs(i);
}
}
pre();
int q;
cin>>q;
for(int i=1;i<=q;i++)
{
int u,v;
cin>>u>>v;
u=2*u;
v=2*v;
cout<<dist(e[u],e[v])<<"\n";
}
cin>>n>>m;
}
return 0;
}