社区讨论

30分RE求条

P7924「EVOI-RD2」旅行家参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mma5qcf2
此快照首次捕获于
2026/03/03 13:18
上周
此快照最后确认于
2026/03/03 19:52
上周
查看原帖
思路:和大家差不多,也是边双缩点,每次询问用LCA差分,最后统计。
代码:
CPP
#include "bits/stdc++.h"
using namespace std;
const int N = 5e5 + 5, M = 2e6 + 5;
int n, m, a[N], stk[N], top, low[N], dfn[N], cnt, in[N], len, 
w[N], st[25][N], fa[N], lg[N], di[N], q, ans;
bool vis[M];
struct node {
	int x, y;
};
vector <node> e[N];
vector <int> te[N];
void tarjan (int x) {
	low[x] = dfn[x] = ++cnt;
	stk[++top] = x;
	for (node i : e[x]) {
		int v = i.x, id = i.y;
		if (vis[id]) continue;
		vis[id] = 1;
		if (!dfn[v]) tarjan (v);
		low[x] = min (low[x], low[v]);//这个写法虽然不正规,但是在求边双和强连通是可以用的,可以通过模板题。(写习惯了)
	}
	if (low[x] == dfn[x]) {
		++len;
		while (stk[top + 1] != x) {
			in[stk[top]] = len;
			w[len] += a[stk[top]];
			top--;
		}
	}
}
void dfs (int x, int f) {
	st[0][dfn[x] = ++cnt] = f;
	fa[x] = f;
	for (int v : te[x]) {
		if (v != f) dfs (v, x);
	}
}
int qmn (int x, int y) {
	return dfn[x] < dfn[y] ? x : y;
}
int lca (int u, int v) {
	if (u == v) return u;
	if ((u = dfn[u]) > (v = dfn[v])) swap (u, v);
	int x = lg[v - u++];
	return qmn (st[u][x], st[v - (1 << x) + 1][x]);
}
void dfss (int x, int fa) {
	for (int v : te[x]) {
		if (v != fa) {
			dfss (v, x);
			di[x] += di[v];
		}
	}
}
int main () {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0); //被卡常后听说能加速。
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		e[u].push_back ({v, i});
		e[v].push_back ({u, i});
	}
	tarjan (1);
	memset (vis, true, sizeof (vis));
	for (int i = 1; i <= n; i++) {
		lg[i + 1] = lg[i + 1 >> 1] + 1;
		for (node j : e[i]) {
			int u = in[i], v = in[j.x];
			if (vis[v] && u != v) {
				vis[v] = false;
				te[u].push_back (v);
			}
		}
		for (int v : te[i]) vis[v] = true;
	}
	cnt = 0;
	dfs (1, 0);
	for (int i = 1; i <= lg[len]; i++) {
		for (int j = 1; j + (1 << i) - 1 <= len; j++) {
			st[i][j] = qmn (st[i - 1][j], st[i - 1][j + (1 << i - 1)]);
		}
	}
	cin >> q;
	for (int i = 1; i <= q; i++) {
		int x, y, z;
		cin >> x >> y;
		x = in[x], y = in[y];
		z = lca (x, y);
		di[x]++; di[y]++; di[fa[z]] -= 2;
	}
	dfss (1, 0);
	for (int i = 1; i <= len; i++) {
		if (di[i]) {
			ans += w[i];
		}
	}
	cout << ans << endl;
	return 0;
}
根本想不出为何RE。
求条啊啊啊啊啊。

回复

4 条回复,欢迎继续交流。

正在加载回复...