zoukankan      html  css  js  c++  java
  • 【题解】食物链

    题目链接

    我来补博客例题了……

    对于本题,我们维护不同物种之间的关系。设有动物A,B,则必有:

    1.A>B

    2.A=b

    3.A<B.

    所以,对于三种关系,我们都需要维护。

    不妨,我们开三倍大小的并查集,其中,1~n是A种群,n+1~2n是B种群,2n+1~3n是C种群,并设有:

    A>B,B>C,C>A.

    每一种动物,在A,B,C种群中都有。设它们的目的,后面再说。

    首先,对于A,B,如果它们是同一物种,那么,我们就需要把三个种群中的A和B全部merge.以此表示它们和平。

    那么,对于A>B(即A吃B)呢?

    从前文知,我们有3个群体,它们之间有捕食与被捕食的关系。那么,我们让A群中的A与B群中的Bmerge,B群中的A与C群中的Bmerge,C群中的A与A群中的Bmerge.

    由于集群中互斥,以此维护其关系。

    那么,考虑如何判断假话。

    首先,对于A=B,则必有A与B互相不大于。即,A不吃B,B不吃A。那么,我们只要判断,A的当前集群的A与B的下一个集群的B是否在同一集合,或是B集群的B与A的下一个集群的A是否在同一集群内。如果符合上述条件,即假话。

    否则,三个集合中的A与B全部合并。

    那么,对于A>B呢(B>A)

    首先,它们不能是同类,判断它们本身是否在一个集合即可。

    其次,它们不能互相克制。即,A>B,B不能>A.

    并查集显而易见了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    inline int read(){
        char ch=getchar();int s=0;
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9'){
            s=(s<<1)+(s<<3)+(ch^48);
            ch=getchar();
        }return s;
    }
    const int MAXN=100010;
    int n,m,ans,f[MAXN+(MAXN<<1)];
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    int main(){
        //freopen("P2024.in","r",stdin);
        //freopen("P2024.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=(n+(n<<1));++i)f[i]=i;
        for(;m;m--){
            int opt=read(),u=read(),v=read();
            if(u>n||v>n){ans++;continue;}
            if(opt==1){
                if(find(u+n)==find(v)||find(u)==find(v+n))ans++;
                else{
                    f[find(u)]=find(v);
                    f[find(u+n)]=find(v+n);
                    f[find(u+(n<<1))]=find(v+(n<<1));
                }
            }else{
                if(find(u)==find(v)||find(u)==find(v+n))ans++;
                else{
                    f[find(u+n)]=find(v);
                    f[find(u+(n<<1))]=find(v+n);
                    f[find(u)]=find(v+(n<<1));
                }
            }
        }
        printf("%d
    ",ans);
        //fclose(stdin);
        //fclose(stdout);
        return 0;
    } 
    View Code

    其实,这道并查集与前面的并查集是有区别的,一者维护路径信息,一者维护多种关系。

  • 相关阅读:
    汇总jQuery的61种选择器及示例
    ACM2028
    Welcome to Erhan Blog
    学习日记-2019529
    3.1-栈
    chrome插件推荐
    Spark RDD
    爬虫-怎么爬静态网站
    一些iOS面试基础题总结
    [PHP] 报错和“@”
  • 原文地址:https://www.cnblogs.com/h-lka/p/11164229.html
Copyright © 2011-2022 走看看