Ural1671-Anansi's Cobweb
2016-11-19 11:10
323 查看
给定一个图中有n个点m条边,往图中不断删边并每次输出图被分成了几块。
使用并查集,相互连边的点放到同一个子集中去,这样一来就可以知道图被分成了几块。
但是并查集只能往里面加边却难以删掉一条特定的边,因此先用不会被删除的边建图,遍历并查集可得到删掉所有特定的边后图被分成的块数,然后往里添加最后被删的那条边,不断往前增加,知道添加到第二条被删的边为止。
在增加边时可以先判断边的两个端点u,v是否处在同一个子集内,如果是则子集的数量不变,反之子集的数量减一。
使用并查集,相互连边的点放到同一个子集中去,这样一来就可以知道图被分成了几块。
但是并查集只能往里面加边却难以删掉一条特定的边,因此先用不会被删除的边建图,遍历并查集可得到删掉所有特定的边后图被分成的块数,然后往里添加最后被删的那条边,不断往前增加,知道添加到第二条被删的边为止。
在增加边时可以先判断边的两个端点u,v是否处在同一个子集内,如果是则子集的数量不变,反之子集的数量减一。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn = 100000 + 5; const int maxm = 100000 + 5; struct edge { int u, v; }; edge e[maxm]; int del[maxm]; bool mark[maxm]; vector<int> ans; int par[maxn]; int rk[maxn]; void init(int n) { for (int i = 0; i < n; i++) { par[i] = i; rk[i] = 0; } } int find(int x) { if (par[x] == x) { return x; } else { return par[x] = find(par[x]); } } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) { return; } if (rk[x] < rk[y]) { par[x] = y; } else { par[y] = x; if (rk[x] == rk[y]) { rk[x]++; } } } bool same(int x, int y) { return find(x) == find(y); } int piece(int n) { int cnt = 0; for (int i = 0; i < n; i++) { if (par[i] == i) { cnt++; } } return cnt; } int main(int argc, char const *argv[]) { int n, m; while (scanf("%d%d", &n, &m) == 2) { for (int i = 0; i < m; i++) { scanf("%d%d", &e[i].u, &e[i].v); } init(n); int q; scanf("%d", &q); for (int i = 0; i < q; i++) { int x; scanf("%d", &x); mark[x-1] = 1; del[i] = x - 1; } for (int i = 0; i < m; i++) { if (!mark[i]) { unite(e[i].u, e[i].v); } } int cnt = piece(n); ans.push_back(cnt); for (int i = q - 1; i >= 1; i--) { int x = e[del[i]].u; int y = e[del[i]].v; if (!same(x, y)) { ans.push_back(--cnt); } else { ans.push_back(cnt); } unite(x, y); } reverse(ans.begin(), ans.end()); for (int i = 0; i < ans.size(); i++) { printf("%d%c", ans[i], i < ans.size() - 1 ? ' ' : '\n'); } memset(mark, 0, sizeof(mark)); memset(del, 0, sizeof(del)); ans.clear(); } return 0; }
相关文章推荐
- Ural 1671 Anansi's Cobweb
- Ural 1671 - Anansi's Cobweb 倒过来做...并查集维护..
- Ural 1671. Anansi's Cobweb(并查集)
- Ural 1671. Anansi's Cobweb
- URAL 1671 Anansi's Cobweb (并查集)
- Ural 1671 Anansi's Cobweb
- URAL 1647 Divide an Island!
- ural 1671 Anansi's Cobweb
- URAL 1777 D - Anindilyakwa 暴力
- Ural_1671. Anansi's Cobweb(并查集)
- ural 1671
- Ural 1671. Anansi's Cobweb(并查集)
- ural 1671 Anansi's Cobweb-并查集
- URAL1671 Anansi's Cobweb(离线做 + 并查集)
- ural 1671
- URAL1671 Anansi's Cobweb(离线做 + 并查集)
- Unicode、ANSI、UTF-8、Unicode Big Endian的故事
- K-based Numbers (URAL 1009)
- tomcat部属项目时报错:An internal error occurred during Add Deployment.java.lang.NullPointerException
- 【leetcode】384. Shuffle an Array