40分求救
查看原帖
40分求救
336082
molarsu楼主2021/12/27 20:39
#include<iostream>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int maxn = 400005;
int n, m, a[maxn], b[maxn], k, usa[maxn], x[maxn], pre[maxn],cnt, head[maxn], ecnt, ans[maxn];
stack<int> destory;
int fd(int y) {
	if (pre[y] == y) return y;
	return y = fd(pre[y]);
}
void hb(int aa, int bb) {
	aa = fd(aa), bb = fd(bb);
	pre[bb] = aa;
}
struct edge {
	int x, nxt;
}e[maxn << 1];
void add_edge(int u, int v) {
	ecnt++;
	e[ecnt].nxt = head[u];
	e[ecnt].x = v;
	head[u] = ecnt;
}
int cntt(int xx) {
	set<int> s;
	for (int i = head[xx]; i; i = e[i].nxt) {
		int u = e[i].x;
		if (!usa[u]) {
			s.insert(fd(u));
		}
	}
	return s.size();
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++)scanf("%d %d", &a[i], &b[i]),add_edge(a[i],b[i]),add_edge(b[i],a[i]);
	for (int j = 0; j < n; j++) {
		pre[j] = j;
	}
	scanf("%d", &k);
	for (int i = 1; i <= k; i++) {
		scanf("%d", &x[i]);
		usa[x[i]] = true;
	}
	for (int i = 0; i < n; i++) {
		if (!usa[a[i]] && !usa[b[i]]) {
			hb(a[i], b[i]);
		}
	}
	for (int i = 0; i < n; i++) {
		if (!usa[i] && fd(i) == i)cnt++;
	}
	ans[k + 1] = cnt;
	for (int j = k; j >= 1; j--) {
		int tmp = x[j];
		usa[tmp] = false;
		bool f = false;
		int cnt1 = cntt(tmp);
		for (int i = head[tmp]; i; i = e[i].nxt) {
			int u = e[i].x;
			int tmpp = fd(u);
			if (!usa[u]) {
				hb(u, tmp);
				f = true;
			}
			if (fd(u) != tmpp)cnt--;
		}
		if (!f)cnt++;
		else cnt -= cnt1, cnt++;
		ans[j] = cnt;
	}
	for (int i = 1; i <= k + 1; i++)cout << ans[i] << endl;
	return 0;
}

反向加边的思路, 一直是40分 第五个点还没输出 求救

2021/12/27 20:39
加载中...