bzoj1015

来源:互联网 发布:天心软件 编辑:程序博客网 时间:2024/06/10 05:35

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

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

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

#include <cstdio>#include <cstring>#define N 440000#define M 220000struct 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;}

原创粉丝点击