P2024 [NOI2001]食物链

https://www.luogu.com.cn/problem/P2024

创建三个集合,1同类域,2捕食域,3天敌域

x y是同类,说明x1-y1,x2-y2,x3-y3;
x吃y 说明x捕食的物种是y的同类(x2 - y1),x是y的天敌(x3-y2)
op = 1的时候,说明x,y是同类,与此矛盾的是x吃y(x2-y1),y吃x(x1-y2)
op = 2的时候,说明x吃y,与此矛盾的是x,y是同类(x1-y1),y吃x(x1-y2)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 10;
int n,k,fa[3 * maxn],sum;
void Init(int n){
    for(int i = 0; i <= 3 * n;i++)
        fa[i] = i;
}

int find(int x){
    if(x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}

void merge(int x,int y){
   fa[find(x)] = find(y);
}

bool same(int x,int y){
    return find(x) == find(y);
}
int main(){
    //freopen("in","r",stdin);
    ios::sync_with_stdio(0);
    cin >> n >> k;
    Init(n);
    while(k--){
        int op,x,y;
        cin >> op >> x >> y;
        if(x < 1 || x > n || y < 1 || y > n){
            sum++;
            continue;
        }
        if(op == 1){//表示x和y是同类
            if(same(x,y + n) || same(x,y + 2 * n))
                sum++;
            else{
                merge(x,y);
                merge(x + n,y + n);
                merge(x + 2 * n,y + 2 * n);
            }
        }else{//x吃y
            if(same(x,y) || same(x,y + 2 * n))
                sum++;
            else{
                merge(x,y + n);
                merge(x + n,y + 2 * n);
                merge(x + 2 * n,y);
            }
        }
    }
    cout << sum;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xcfxcf/p/12301567.html