求条,样例没过qwq(马蜂良好)
查看原帖
求条,样例没过qwq(马蜂良好)
838570
Double_Sheep楼主2024/5/15 19:57

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;
}
2024/5/15 19:57
加载中...