[bzoj1015][JSOI2008]星球大战——并查集+离线处理
2017-02-23 15:56
405 查看
题解
给定一张图,支持删点和询问连通块个数
按操作顺序处理的话要在删除点的同时维护图的形态(即图具体的连边情况),这是几乎不可做的
我们发现,这道题可以先读入操作,把没删的点的边先连上,然后再倒序处理操作
这样的话从删点变成了加点,而且只要维护连通块的数量,用并查集可以快速的解决这个问题
代码
#include <bits/stdc++.h> using namespace std; const int maxn = 4 * 200000; int n, m, q[maxn]; vector<int> G[maxn]; int fa[maxn], added[maxn], des[maxn], ans[maxn]; int tot = 0; int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]); } void add(int x) { int p = find(x), q; added[x] = 1; for (int i = 0; i < G[x].size(); i++) { if (added[G[x][i]]) { q = find(G[x][i]); if (p != q) { fa[q] = p; tot--; //连通块少一个 } } } } int main() { // freopen("input", "r", stdin); scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) { int x, y; scanf("%d %d", &x, &y); G[x].push_back(y); G[y].push_back(x); } memset(added, 0, sizeof(added)); for (int i = 0; i < n; i++) fa[i] = i; int d; scanf("%d", &d); for (int i = 1; i <= d; i++) { scanf("%d", &q[i]); des[q[i]] = 1; } for (int i = 0; i < n; i++) { if (!des[i]) { tot++; add(i); added[i] = 1; } } ans[d + 1] = tot; for (int i = d; i > 0; i--) { tot++; //连通块多一个 add(q[i]); added[q[i]] = 1; ans[i] = tot; } for (int i = 1; i <= d + 1; i++) printf("%d\n", ans[i]); return 0; }
相关文章推荐
- BZOJ 1015 [JSOI2008]星球大战——并查集+离线处理
- BZOJ1015: [JSOI2008]星球大战starwar 并查集 离线处理
- [Bzoj1015][JSOI2008]星球大战starwar(并查集)(离线处理)
- bzoj 1015: [JSOI2008]星球大战starwar 并查集+离线处理
- bzoj1015 [JSOI2008]星球大战(离线操作+并查集)
- BZOJ 1015: [JSOI2008]星球大战starwar(并查集求连通块+离线处理)
- 【bzoj1015】【JSOI2008】【星球大战】【并查集+离线】
- BZOJ-1015 StarWar星球大战 并查集+离线处理
- 【bzoj1015】【JSOI2008】【星球大战】【并查集+离线】
- BZOJ-1015 StarWar星球大战 并查集+离线处理
- 【JSOI2008】bzoj1015 星球大战
- [题解] JSOI2008 星球大战 (并查集+逆序处理)
- BZOJ_1015_星球大战_[JSOI2008]_(并查集)
- [bzoj1015](JSOI2008)星球大战 starwar(离线+并查集)
- BZOJ 1015: [JSOI2008]星球大战starwar 并查集 离线维护
- 【bzoj1015】【JSOI2008】【星球大战】【starwar】【并查集】
- BZOJ 1015 JSOI2008 星球大战 starwar 并查集
- 星球大战 bzoj1015 luogu1197 JSOI2008
- 【BZOJ1015】【JSOI2008】星球大战 并查集
- [bzoj 1015] [JSOI2008]星球大战starwar:并查集,离线