bzoj1015

有向图的连通性用强连通,无向图的连通性用并查集,起码90%的题都可以这么做。

但是这题是不停的删边,并查集根本忍不了啊。

那就倒过来弄呗~一点一点加边存答案,再从头输出

#include <cstdio>
#include <cstring>
#define N 440000
#define M 220000
struct EDGE {
	int to, next;
}edge[2*M];
bool flag[N];
int head[N], q[N], fa[N], ans[N];
int n, m, cnt, K;
inline void add(int x, int y) {
	edge[++cnt].to = y;
	edge[cnt].next = head[x]; head[x] = cnt;
	return ;
}
inline int getfa(int x) {
	int r = x;
	while(r != fa[r]) r = fa[r];
	while(x != fa[x]) {int temp = x; x = fa[x]; fa[temp] = r;}
	return r;
}
int main() {
	freopen("1015.in", "r", stdin);
	scanf("%d%d", &n, &m);
	memset(head, 0, sizeof(head)); cnt = 0;
	for(int i = 1; i <= m; ++i) {
		int x, y; scanf("%d%d", &x, &y);
		add(x, y); add(y, x);
	}
	memset(flag, false, sizeof(flag));
	scanf("%d", &K);
	for(int i = 1; i <= K; ++i) scanf("%d", q+i), flag[q[i]] = true;
	int num = n - K;
	for(int i = 0; i < n; ++i) fa[i] = i;
	for(int i = 0; i < n; ++i)
		if(!flag[i]) {
			for(int j = head[i]; j; j = edge[j].next) {
				int y = edge[j].to;
				if(!flag[y]) {
					int fax = getfa(i), fay = getfa(y);
					if(fax != fay) fa[fay] = fax, --num;
				}
			}
		}
	ans[K] = num;
	for(int i = K; i > 0; --i) {
		int x = q[i]; flag[x] = false; ++num;
		for(int j = head[x]; j; j = edge[j].next) {
			int y = edge[j].to;
			if(!flag[y]) {
				int fax = getfa(x), fay = getfa(y);
				if(fax != fay) fa[fay] = fax, --num;
			}
		}
		ans[i - 1] = num;
	}
	for(int i = 0; i <= K; ++i) printf("%d\n", ans[i]);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值