zoukankan      html  css  js  c++  java
  • 【NOI2001】【Vijos1531】食物链(并查集拓展域)

    problem

    • 森林中有3种动物:A吃B,B吃C,C吃A
    • 现有 N 个动物(编号1~n),K句话。
      1、1 X Y,表示 X 和 Y 是同类。
      2、2 X Y,表示 X 吃 Y。
    • 一句话是假话当且仅当:
      1、与前面的冲突。
      2、X吃X。
      3、编号大于N。
    • 判断当前话的真假。

    solution

    一、考虑补集:

    • 把每个动物x拆成三个节点:其中i用来连接与i同类的,i+n用来连接能吃i的,i+2*n用来连接i能吃的。(具体来说,凡是与i+n节点在同一个集合里的,都是被i吃的动物。)

    二、考虑合并:

    • 对于X和Y是同类:则说明“X的同类”与“Y的同类”一样,“X的捕食”与“Y的捕食”一样,“X的天敌”与“Y的天敌”一样。我们分别合并这三个节点。
    • 对于X吃Y这样:说明“X的捕食”就是“Y的同类”,“X的同类”就是“Y的天敌”,又因为是环形,所以“X的天敌”就是“Y的捕食”。

    三、考虑真假

    • 对于X和Y是同类,当且仅当以下2种时出现矛盾:
      1、X吃Y。
      2、Y吃X。
    • 对于X吃Y,当且仅当以下2种时出现矛盾:
      1、X和Y是同类。
      2、Y吃X。
    • 分别判断对应节点是否在同一集合即可。

    codes

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int ans = 0;
    int fa[50010*3];
    void init(int n){ for(int i = 1; i <= n; i++)fa[i]=i; }
    int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); }
    void merge(int x, int y){ x=find(x);y=find(y);if(x!=y)fa[x]=y;}
    int some(int x, int y){ return find(x)==find(y); }
    int main(){
        int n, m;
        cin>>n>>m;
        init(n*3);
        for(int i = 1; i <= m; i++){
            int op, x, y;
            cin>>op>>x>>y;
            if(x>n||y>n){ans++;continue;}//2)当前的话中X或Y比N大,就是假话
            if(op==2&&x==y){ans++;continue;}//3)当前的话表示X吃X,就是假话
            if(op==1){
                if(some(x,y+n)||some(y,x+n))ans++;//如果x吃y或者y吃x,就不是同类
                else{
                    merge(x,y);//x和y是同类
                    merge(x+n,y+n);//能吃x和y的也是同类
                    merge(x+n*2,y+n*2);//x和y能吃的也是同类
                }
            }else{
                if(some(x,y)||some(y,x+n))ans++;//如果x和y是同类或者y吃x
                else{
                    merge(x,y+n);//x和吃y的连起来
                    merge(x+n,y+n*2);//能吃x的和被y吃的连起来(三种动物之间的关系啊)
                    merge(x+n*2,y);//x能吃的和y连起来
                }
            }
        }
        cout<<ans<<"
    ";
        return 0;
    }
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/gwj1314/p/9444901.html
Copyright © 2011-2022 走看看