chenfy27的刷题记录

导航

luoguP2024 食物链

动物王国中有3类动物A,B,C,构成食物链:A吃B,B吃C,C吃A。现有N个动物,每个动物都是A,B,C中的一种,有K个描述:

  • 1 X Y,表示X和Y是同类
  • 2 X Y,表示X吃Y

当一句话满足以下条件之一时,为假话,否则为真话。

  • 与前面的话有冲突
  • X或Y比N大
  • X吃X

输出假话总数。

提示:种类并查集,对每个动物x,建立虚拟动物x1和x2,并且x吃x1,x2吃x。建虚拟节点是为了方便维护种类之间的关系。

#include <bits/stdc++.h>
using i64 = long long;

// DSU模板...

void solve() {
    int N, K;
    std::cin >> N >> K;
    DSU dsu(3*N);
    
    auto predator = [&](int x) {
        return x + 2 * N;
    };
    auto predatee = [&](int x) {
        return x + 1 * N;
    };
    
    int ans = 0;
    for (int i = 0; i < K; i++) {
        int op, x, y;
        std::cin >> op >> x >> y;
        if (x > N || y > N) {
            ans += 1;
            continue;
        }
        x--, y--;
        if (op == 1) {
            if (dsu.same(x, predator(y)) || dsu.same(y, predator(x))) {
                ans += 1;
            } else {
                dsu.join(x, y);
                dsu.join(predator(x), predator(y));
                dsu.join(predatee(x), predatee(y));
            }
        } else if (op == 2) {
            if (dsu.same(x, predator(y))) {
                ;
            } else if (dsu.same(x, y) || dsu.same(y, predator(x))) {
                ans += 1;
            } else {
                dsu.join(x, predator(y));
                dsu.join(predatee(x), y);
                dsu.join(predator(x), predatee(y));
            }
        }
    }
    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

posted on 2024-06-19 22:00  chenfy27  阅读(18)  评论(0)    收藏  举报