rt.
刚学圆方树不太熟练,但是看了很久都没看出问题。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n,m,q,num,head[N],tot,fa[N],dep[N],head2[N],tot2;
int dfn[N],low[N],cnt,sum[N],sz[N],son[N],Top[N];
//sum是统计圆方树上圆点个数
stack<int> s;
struct edge {int v,nxt;}e[N << 1],g[N << 1];
//e是输入的图,g是圆方树
void add(int u,int v) {
e[++tot] = edge {v,head[u]};
head[u] = tot;
}
void add2(int u,int v) {
g[++tot2] = edge {v,head2[u]};
head2[u] = tot2;
}
void tarjan(int u,int f) {
dfn[u] = low[u] = ++cnt; s.push(u);
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v; if(v == f) continue;
if(!dfn[v]) {
tarjan(v,u);
low[u] = min(low[u],low[v]);
if(low[v] >= dfn[u]) {
num++,add2(num,u),add2(u,num);
while(s.size() && s.top() != v)
add2(num,s.top()),add2(s.top(),num),s.pop();
}
} else low[u] = min(low[u],dfn[v]);
}
}
void dfs(int u,int f) {
fa[u] = f,dep[u] = dep[f] + 1,sz[u] = 1;
sum[u] = sum[f] + (u <= n); //圆点
for(int i = head2[u];i;i = g[i].nxt) {
int v = g[i].v; if(v == f) continue;
dfs(v,u); sz[u] += sz[v];
if(sz[son[u]] < sz[v]) son[u] = v;
}
}
void dfs2(int u,int top) {
Top[u] = top;
if(son[u]) dfs2(son[u],top);
for(int i = head2[u];i;i = g[i].nxt) {
int v = g[i].v;
if(v != son[u] && v != fa[u]) dfs2(v,v);
}
}
int LCA(int u,int v) {
while(Top[u] != Top[v]) {
if(dep[Top[u]] < dep[Top[v]]) swap(u,v);
u = fa[Top[u]];
}
return dep[u] < dep[v] ? u : v;
}
int main() {
scanf("%d%d",&n,&m); num = n;
for(int i = 1;i <= m;i++) {
int u,v; scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
for(int i = 1;i <= n;i++)
if(!dfn[i]) tarjan(i,0);
dfs(1,0),dfs2(1,1);
scanf("%d",&q);
while(q--) {
int u,v; scanf("%d%d",&u,&v); int lca = LCA(u,v);
printf("%d\n",sum[u] + sum[v] - sum[lca] - sum[fa[lca]]);
}
return 0;
}