网络(network) 题解

\(\text{网络(network) 题解}\)

为了讨好 YQS 被迫上工写题解。

这个限制有些迪克,抽象一下,发现实际上限制的是 \(x,y\) 不能同时带电。这个 \(\dfrac n2\) 的限制不是白给的,考虑如何利用,实际上常见的方法是两两分组处理。对于分组 \((x,to_x),(y,to_y)\),改变一下组合成为 \((x,y),(to_x,to_y)\) 显然同样能够保证合法性。那么我们可以正着先做一遍改变分组的形式。

现在考虑如何统计答案。不难发现最终形成的两两组合只需要任意选择一个带电即可。那么先任意钦定一个带电,从后往前递推,如果 \(y\) 带电答案就为 \(1\)。但现在需要考虑我们前面做变换的意义实际上是钦定原先的 \(to_x,to_y\) 只有一个带电的情况下确定 \(x,y\) 两点之间的方向再考虑是否做变换,所以此时 \(x,y\) 的取值应该依据原先的 \(to_x,to_y\) 重新进行变换即可,因此需要记一个每个位置改变组合之前的实际取值。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 5e6 + 5;
int n, m;
int x[N], y[N];
int elc[N], to[N], bex[N], bey[N];
int ans[N];

int main() {
	freopen("network.in", "r", stdin);
	freopen("network.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	if (n & 1) ++n;
	for (int i = 1; i <= m; i++) cin >> x[i] >> y[i];
	for (int i = 1; i <= n; i += 2) to[i] = i + 1, to[i + 1] = i;
	for (int i = 1; i <= m; i++) {
		int tx = to[x[i]], ty = to[y[i]];
		bex[i] = tx, bey[i] = ty;
		to[x[i]] = y[i];
		to[y[i]] = x[i];
		to[tx] = ty;
		to[ty] = tx;
	}
	for (int i = 1; i <= n; i++)
		if (i < to[i]) elc[i] = 1;
	for (int i = m; i; --i) {
		if (elc[y[i]]) ans[i] = 1;
		int tx = bex[i], ty = bey[i];
		if (!elc[tx]) elc[x[i]] = 1, elc[y[i]] = 0;
		if (!elc[ty]) elc[y[i]] = 1, elc[x[i]] = 0;
		to[x[i]] = tx;
		to[tx] = x[i];
		to[y[i]] = ty;
		to[ty] = y[i];
	}
	cout << "YES\n";
	for (int i = 1; i <= m; i++) cout << ans[i];
	cout << '\n';
	return 0;
}
posted @ 2025-09-14 21:15  长安19路  阅读(17)  评论(0)    收藏  举报