• A Bug's Life POJ


    这个题目的写法有很多,用二分图染色也可以写,思路很好想,这里我们用关于并查集的两种写法来做。

    题目大意:输入x,y表示x和y交配,然后判断是否有同性恋。

    1 带权并查集:

      我们可以用边的权值来表示一种关系,比如说

    我们可以设权值为1,假如A和B发生关系,B和C发生关系,那么C到A的距离就是2,如果A和C发生关系,那就会产生矛盾,因此A和C是同性。

    所以如果x和y可以发生关系,首先x和y必须在一棵树上,并且x和y到跟的距离必须同为奇数或者同为偶数。

    code:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=2000+3;
    int fa[N],w[N];
    int find(int x){
        if(x==fa[x]) return x;
        else {
            int c=find(fa[x]);
            w[fa[x]]%=2;
            w[x]=(w[x]+w[fa[x]])%2;
            return fa[x]=c;
        }
    }
    bool unite(int x,int y){
        int fx=find(x),fy=find(y);
        if(fx!=fy){
            fa[fx]=fy;
            w[fx]=(w[y]-w[x]+1)%2;
            return 0;
        }
        else {
            return w[x]%2==w[y]%2;
        }
    }
    void solve(int time){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++){
            fa[i]=i;
            w[i]=0;
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            if(ans) continue ;
            if(unite(x,y)){
                ans++;
            //    break;//注意这里不能直接break...wa了好几发,但是CF是可以的。。。 
            }
        }
        printf("Scenario #%d:
    ",time);
        if(ans) puts("Suspicious bugs found!
    ");
        else puts("No suspicious bugs found!
    ");
    }
    int main(){
        int t;cin>>t;
        for(int i=1;i<=t;i++) solve(i);
        return 0;
    }

    2 种类并查集:

      如果用种类并查集来写,那这个题就相当于 食物链 那道题目的缩水版。。。

      将每个元素分为两类,x和x+n,如果x和y可以发生关系,那么x和y不能是同类,也就是说x和y不能是一类,x+n和y+n不能是一类。

      code:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=2000+3;
    int fa[N+N];
    int find(int x){
        return fa[x]==x? x:fa[x]=find(fa[x]);
    }
    int unite(int x,int y){
        int fx=find(x),fy=find(y);
        fa[fx]=fy;
    }
    bool same(int x,int y){
        return find(x)==find(y);
    }
    void solve(int time){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n+n;i++) fa[i]=i;
        int ans=0;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            x--;y--;
            if(ans) continue ;
            if(same(x,y)||same(x+n,y+n)){
                ans=1;
    //            if(ans) break;//注意这里不能直接break...wa了好几发,但是CF是可以的。。。 
            }
            else {
                unite(x,y+n);unite(y,x+n);
            }
        }
        printf("Scenario #%d:
    ",time);
        if(ans) puts("Suspicious bugs found!
    ");
        else puts("No suspicious bugs found!
    ");
    }
    int main(){
        int t;cin>>t;
        for(int i=1;i<=t;i++) solve(i);
        return 0;
    }
  • 相关阅读:
    Python程序员用文字加密的方式,给女程序员写情书,一周后牵手回家
    小学生在网吧用python抓取LOL英雄皮肤,步骤简单
    vuex中module的命名空间概念
    动态设置html的font-size值
    JavaScript判断各种数据类型
    vuex脑图
    作用域链和函数内部this指向问题以及bind、call、apply方法
    BOM
    jQuery_base
    js_base_note
  • 原文地址:https://www.cnblogs.com/Accepting/p/12649735.html
Copyright © 2020-2023  润新知