目录
- 1 介绍
- 2 训练
- 3 参考
1 介绍
本专题用来记录并查集相关的题目。
并查集模板:
//初始化
for (int i = 1; i <= n; ++i) { //n为结点数目p[i] = i;
}//查找
find(int x) {if (p[x] != x) p[x] = find(p[x]);return p[x];
}//合并
int pa = find(a);
int pb = find(b);
if (pa != pb) {p[pa] = pb;
}
2 训练
题目1:1250格子游戏
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 210;
int n, m;
int p[N * N];int find(int x) {if (p[x] != x) p[x] = find(p[x]);return p[x];
}int main() {cin >> n >> m;for (int i = 0; i < n * n; ++i) p[i] = i;for (int i = 1; i <= m; ++i) {int x, y;char op;cin >> x >> y >> op;int a, b;if (op == 'D') {a = (x - 1) * n + y - 1;b = x * n + y - 1;} else {a = (x - 1) * n + y - 1;b = (x - 1) * n + y;}int pa = find(a);int pb = find(b);if (pa == pb) {cout << i << endl;return 0;} else {p[pa] = pb;}}cout << "draw" << endl;return 0;
}
题目2:1252搭配购买
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>using namespace std;const int N = 10010;
int n, m, W;
int c[N], w[N];
int p[N];
int sc[N]; //每个连通块的总价格,只针对根结点
int sw[N]; //每个连通块的总价值
int f[N];int find(int x) {if (p[x] != x) p[x] = find(p[x]);return p[x];
}int main() {cin >> n >> m >> W;for (int i = 1; i <= n; ++i) {cin >> c[i] >> w[i];}for (int i = 1; i <= n; ++i) {p[i] = i;sc[i] = c[i];sw[i] = w[i];}for (int i = 1; i <= m; ++i) {int a, b;cin >> a >> b;int pa = find(a);int pb = find(b);if (pa != pb) {p[pa] = pb;sc[pb] += sc[pa];sw[pb] += sw[pa];}}//01背包问题int idx = 0;for (int i = 1; i <= n; ++i) {if (i == p[i]) {sc[idx] = sc[i];sw[idx] = sw[i];idx++;}}for (int i = 0; i < idx; ++i) {for (int j = W; j >= sc[i]; --j) {f[j] = max(f[j], f[j - sc[i]] + sw[i]);}}cout << f[W] << endl;return 0;
}
题目3:237程序自动分析
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>using namespace std;typedef pair<int, int> PII;const int N = 200010, M = 1e9 + 10;
int p[N];int find(int x) {if (p[x] != x) p[x] = find(p[x]);return p[x];
}int main() {int T;cin >> T;while (T--) {memset(p, 0, sizeof p);unordered_map<int, int> map_b_s;int n;cin >> n;vector<PII> equals, not_equals;int idx = 0;for (int i = 0; i < n; ++i) {int a, b, c;cin >> a >> b >> c;if (c == 0) {not_equals.emplace_back(a,b);} else {equals.emplace_back(a,b);}if (map_b_s.count(a) == 0) {map_b_s[a] = idx++;}if (map_b_s.count(b) == 0) {map_b_s[b] = idx++;}}for (int i = 0; i < idx; ++i) p[i] = i;for (auto [a, b] : equals) {a = map_b_s[a];b = map_b_s[b];int pa = find(a);int pb = find(b);if (pa != pb) {p[pa] = pb;}}bool flag = true;for (auto [a, b] : not_equals) {a = map_b_s[a];b = map_b_s[b];int pa = find(a);int pb = find(b);if (pa == pb) {flag = false;cout << "NO" << endl;break;}}if (flag) {cout << "YES" << endl;}}return 0;
}
题目4:239奇偶游戏
C++代码如下,
//带边权写法
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>using namespace std;const int N = 20010;int n, m;
int p[N], d[N];
unordered_map<int, int> S;int get(int x) {if (S.count(x) == 0) S[x] = ++n;return S[x];
}int find(int x) {if (p[x] != x) {int root = find(p[x]);d[x] += d[p[x]];p[x] = root;}return p[x];
}int main() {cin >> n >> m;n = 0;for (int i = 0; i < N; ++i) p[i] = i;int res = m;for (int i = 1; i <= m; ++i) {int a, b;string type;cin >> a >> b >> type;a = get(a - 1), b = get(b);int t = 0;if (type == "odd") t = 1;int pa = find(a), pb = find(b);if (pa == pb) {if (((d[a] + d[b]) % 2 + 2) % 2 != t) {res = i - 1;break;}} else {p[pa] = pb;d[pa] = d[a] ^ d[b] ^ t;}}cout << res << endl;return 0;
}
题目5:238银河英雄传说
C++代码如下,
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 30010;
int n;
int p[N];
int d[N]; //到根结点的距离
int cnt[N];int find(int x) {if (p[x] != x) {int root = find(p[x]);d[x] += d[p[x]];p[x] = root;}return p[x];
}int main() {cin >> n;for (int i = 1; i < N; ++i) {p[i] = i;cnt[i] = 1;d[i] = 0;}for (int i = 0; i < n; ++i) {char op;int a, b;cin >> op >> a >> b;int pa = find(a), pb = find(b);if (op == 'M') {if (pa != pb) {d[pa] = cnt[pb];cnt[pb] += cnt[pa];p[pa] = pb; }} else {if (pa != pb) puts("-1");else {cout << max(abs(d[a] - d[b]) - 1, 0) << endl;}}}return 0;
}
3 参考
acwing算法基础之数据结构–并查集算法