赞
踩
本专题用来记录并查集相关的题目。
并查集模板:
//初始化 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; }
题目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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。