圆方树过样例全 WA 求助
查看原帖
圆方树过样例全 WA 求助
767449
KukCair楼主2025/1/15 13:44

目测是都少(或多) 1。

#include <bits/stdc++.h>
using namespace std;
int t, n, m, cnt, pos, u[200005], w[400005], pa[400005][23], dep[400005], low[200005], dfn[200005];
bool f[200005];
vector<int> vc[200005], g[400005];
stack<int> st;
void dfs(int x, int fa){
	pa[x][0] = fa;
	dfn[x] = ++cnt;
	dep[x] = dep[fa] + 1;
	w[x] = w[fa] + (x <= n);
	for(int i = 0; i < g[x].size(); i++){
		int v = g[x][i];
		if(v != fa)
			dfs(v, x);
	}
}
void painit(){
	for(int i = 1; i <= 21; i++)
		for(int j = 1; j <= pos; j++)
			pa[j][i] = pa[pa[j][i - 1]][i - 1];
}
int fly(int x, int d){
	for(int i = 0; i <= 21; i++)
		if((d >> i) & 1)
			x = pa[x][i];
	return x;
}
int LCA(int x, int y){
	if(dep[x] > dep[y]) swap(x, y);
	y = fly(y, dep[y] - dep[x]);
	if(x == y) return x;
	for(int i = 21; i >= 0; i--){
		if(pa[x][i] != pa[y][i]){
			x = pa[x][i];
			y = pa[y][i];
		}
	}
	return pa[x][0];
}
void tarjan(int x){
	f[x] = 1;
	st.push(x);
	low[x] = dfn[x] = ++cnt;
	for(int i = 0; i < vc[x].size(); i++){
		int v = vc[x][i];
		if(!dfn[v]){
			tarjan(v);
			low[x] = min(low[x], low[v]);
			if(low[v] == dfn[x]){
				pos++;
				int t = st.top();
				st.pop();
				g[pos].push_back(t);
				g[t].push_back(pos);
				while(t != v){
					t = st.top();
					st.pop();
					g[pos].push_back(t);
					g[t].push_back(pos);
				}
				g[pos].push_back(x);
				g[x].push_back(pos);
			}
		}
		else if(f[v]) low[x] = min(low[x], dfn[v]);
	}
}
bool cmp(int x, int y){
	return dfn[x] < dfn[y];
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> t;
	while(t--){
		for(int i = 1; i <= pos; i++) g[i].clear();
		memset(pa, 0, sizeof(pa));
		memset(w, 0, sizeof(w));
		memset(f, 0, sizeof(f));
		while(st.size()) st.pop();
		cin >> n >> m;
		pos = n;
		for(int i = 1; i <= n; i++) vc[i].clear();
		for(int i = 1; i <= m; i++){
			int u, v;
			cin >> u >> v;
			vc[u].push_back(v);
			vc[v].push_back(u);
		}
		cnt = 0;
		tarjan(1);
		cnt = 0;
		dfs(1, 0);
		painit();
		int q;
		cin >> q;
		while(q--){
			int S, ans = 0;
			cin >> S;
			for(int i = 1; i <= S; i++) cin >> u[i];
			sort(u + 1, u + S + 1, cmp);
			u[S + 1] = u[1];
			for(int i = 1; i <= S; i++){
				int lca = LCA(u[i], u[i + 1]);
				ans += w[u[i]] + w[u[i + 1]] - w[lca] * 2;
			}
			cout << ans / 2 - S + (LCA(w[1], w[S]) <= n) << '\n';
		}
	}
	return 0;
}
2025/1/15 13:44
加载中...