2 条题解

  • 0
    @ 2025-12-3 18:10:58

    按题意直接模拟即可。(代码里都有注释)

    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
      @ 2025-9-14 20:21:40

      这是经典并查集题目:

      把每个电荷拆成两个结点 i,i′i,i'。

      • A x y 时连边 x↔yx \leftrightarrow y 和 x′↔y′x' \leftrightarrow y'。
      • A x y 时连边 x↔y′x \leftrightarrow y' 和 x′↔yx' \leftrightarrow y。
      • Q x y 时:
        • xx 与 yy 连通就输出 A。
        • xx 与 y′y' 连通就输出 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
      上传者