[并查集]食物链

经典老题了

上次做是开一个3n的并查集。
对同类的处理比较平凡。
对X吃Y:
如果发现实际上X连接了模意义下距离为0或2的Y,说明这句话是假的。
顺时针循环连接X与下一块中的Y, 使Y与X在模意义下距离为1。(Y=X++)

#include<bits/stdc++.h>
using namespace std;

int n, k, ans, f[200005];
int find (int x) {return x == f[x] ? f[x] : f[x] = find(f[x]);}
bool check (int x, int y) {return find(x) == find(y);}
void merge (int x, int y) {f[find(x)] = find(y);}

int main() {
  cin >> n >> k;
  for (int i = 1; i <= n * 3; i++) f[i] = i;
  for (int i = 1; i <= k; i++) {
    int opt, x, y;
    cin >> opt >> x >> y;
    if (x > n || y > n) ans++;
    else if (opt == 1) {
      if (check(x, y + n) || check(x, y + 2 * n)) ans++;
      else {
        merge(x, y);
        merge(x + n, y + n);
        merge(x + 2 * n, y + 2 * n);
      }
    }
    else if(opt == 2) {
      if (check(x, y) || check(x, y + 2 * n)) ans++;
      else {
        merge(x, y + n);
        merge(x + n, y + 2 * n);
        merge(x + 2 * n, y);
      }
    }
  }
  cout << ans;
  return 0;
}

这次根据acwing的思路整了个带权并查集,通过维护与根节点的距离判断种类。

#include <iostream>
#include <cstdio>
using namespace std;

const int maxn = 5e4 + 10;

int n, m;
int f[maxn], d[maxn];

int find(int x) {
  //x == f[x] ? f[x] : f[x] = find(f[x]);
  if (x != f[x]) {
    int t = find(f[x]);//找根并更新d[f[x]]
    d[x] += d[f[x]];//更新d[x]为到根的距离
    f[x] = t; 
  }
  return f[x];
}

int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) f[i] = i;

  int ans = 0;
  while (m--) {
    int op, x, y;
    scanf("%d%d%d", &op, &x, &y);
    if (x > n || y > n) ans++;
    else {
      int px = find(x), py = find(y);
      if (op == 1) {
        if (px == py && (d[x] - d[y]) % 3 != 0) ans++;
        else if (px != py) {
          f[px] = py;
          //(dx + ? - dy) mod 3 = 0
          d[px] = d[y] - d[x];
        } 
      }
      if (op == 2) {
        //dx - dy 同余 1
        if (px == py && (d[x] - d[y] - 1) % 3 != 0) ans++;
        else if (px != py) {
          f[px] = py;
          //(dx + ? - dy - 1) mod 3 = 0  
          d[px] = d[y] + 1 - d[x];
        }
      }
    }
  }
  printf("%d", ans);
  return 0;
}
posted @ 2021-10-29 23:53  _vv123  阅读(39)  评论(0编辑  收藏  举报