2 条题解
-
0
按题意直接模拟即可。(代码里都有注释)
AC code:
#include<bits/stdc++.h> using namespace std; const int MAXN = 200005; int parent[MAXN]; int rank_[MAXN]; int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); // 路径压缩 } return parent[x]; } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) return; // 按秩合并 if (rank_[x] < rank_[y]) { parent[x] = y; } else { parent[y] = x; if (rank_[x] == rank_[y]) { rank_[x]++; } } } int main() { int N, Q; scanf("%d %d", &N, &Q); // 初始化并查集:节点 1~N 表示正电荷,N+1~2N 表示负电荷 for (int i = 1; i <= 2 * N; i++) { parent[i] = i; rank_[i] = 0; } while (Q--) { char op[2]; int a, b; scanf("%s %d %d", op, &a, &b); if (op[0] == 'A') { // A操作:a 和 b 互相吸引,合并 a 与 b+N,a+N 与 b unite(a, b + N); unite(a + N, b); } else if (op[0] == 'R') { // R 操作:a 和 b 互相排斥,合并 a 与 b,a+N 与 b+N unite(a, b); unite(a + N, b + N); } else if (op[0] == 'Q') { // Q 操作:查询 a 和 b 的关系 if (find(a) == find(b)) { printf("R\n"); // 同一集合,排斥 } else if (find(a) == find(b + N)) { printf("A\n"); // a 的正电荷与 b 的负电荷同一集合,吸引 } else { printf("?\n"); // 无法确定 } } } return 0; } -
0
这是经典并查集题目:
把每个电荷拆成两个结点 。
A x y时连边 和 。A x y时连边 和 。Q x y时:- 与 连通就输出
A。 - 与 连通就输出
R。 - 都不连通就输出
?。
- 与 连通就输出
#include <bits/stdc++.h> using namespace std; int ld[1000012], co[1000012], sz[1000012]; void init(int n) { for (int i = 1; i <= n; i++) ld[i] = i, co[i] = 0, sz[i] = 1; } pair<int, int> want(int x) { stack<pair<int, int> > s; s.push(make_pair(x, 0)); int tc = 0, y = x; while (ld[x] != x) { tc += co[x]; x = ld[x]; s.push(make_pair(x, tc)); } while (!s.empty()) { pair<int, int> u = s.top(); s.pop(); ld[u.first] = x; co[u.first] = tc - u.second; } return make_pair(ld[y], co[y]); } void add(int x, int y, int c) { x = want(x).first, y = want(y).first; if (x == y) return; ld[y] = x, co[y] = c, sz[x] += sz[y], sz[y] = 0; } bool tg(int x, int y) { pair<int, int> xx = want(x), yy = want(y); return (xx.first == yy.first); } int dis(int x, int y) { pair<int, int> xx = want(x), yy = want(y); return xx.second - yy.second; } int main() { int n, m; cin >> n >> m; init(2 * n); while (m--) { char c; int x, y; cin >> c >> x >> y; if (c == 'A') add(x, y + n, 0), add(x + n, y, 0); if (c == 'R') add(x, y, 0), add(x + n, y + n, 0); if (c == 'Q') { if (tg(x, y + n)) puts("A"); else if (tg(x, y)) puts("R"); else puts("?"); } } return 0; }
- 1
信息
- ID
- 118
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 5
- 已通过
- 3
- 上传者