zoukankan      html  css  js  c++  java
  • 【并查集】poj 2492 A Bug's Life(二集合问题)

    题目描述:

    http://poj.org/problem?id=2492

     

    中文大意:

    H 教授正在研究一种稀有臭虫的性行为。

    他猜测该类昆虫具有两种性别,并且是异性交配。

    已知几组交配数据,判断他的猜测是否存在 bug。

     

    思路:

    我们规定:若 i 属于集合 A ,则 i+n 属于集合 B。

    两种性别可以抽象为两个集合,x 和 y 是两只交配的昆虫。

    若 x 和 y 属于不同的集合,则 x 和 y+n 属于同一集合,y 和 x+n 属于同一集合;

    若 x 和 y 属于相同的集合,则说明 H 教授的猜测存在 bug。

    代码:

    #include<iostream>
    using namespace std;
    
    int n,m; 
    int sets[4002];//各节点的所属集 
    int height[4002];//各集合的树高 
    
    //初始化,各节点分别属于独立的集合 
    void init(int n){
        for(int i=1;i<=n;i++){
            sets[i] = i;
            height[i] = 1;
        }
    }
    
    //寻找节点 x 的所属集 
    int find(int x){
        //寻找根节点 
        int root = x;
        while(root != sets[root]){
            root = sets[root];
        }
        
        //路径压缩:将路径上节点的所属集修改为根节点 
        int i = x;
        while(sets[i] != root){
            int j = sets[i];
            sets[i] = root;
            i = j;
        }
        return root;
    }
    
    //合并 
    void union_set(int x, int y){
        //寻找节点 x 的所属集 
        x = find(x);
        //寻找节点 y 的所属集 
        y = find(y);
        
        //若两个节点的所属集树高相同,则将 x 的所属集并到 y 的所属集 
        if(height[x] == height[y]){
            sets[x] = y;
            height[y]++;
        }//否则,将矮树并到高树,且高树的树高保持不变 
        else if(height[x] > height[y]){
            sets[y] = x;
        } 
        else{
            sets[x] = y; 
        } 
    }
    
    int main(){
        int t;
        scanf("%d", &t);
        for(int k=1;k<=t;k++){
            //存在空行 
            if(k != 1){
                printf("
    ");
            }
            
            scanf("%d %d", &n, &m);
            init(2*n);
            
            bool have_bug = false;//是否有 bug 
            int x,y;
            for(int i=0;i<m;i++){
                scanf("%d %d", &x, &y);
                //若节点 x 和节点 y 属于不同集合 
                if(find(x) != find(y)){
                    //规定:如果节点 i 属于集合 A,则 i+n 属于集合 B 
                    union_set(x, y+n);
                    union_set(y, x+n); 
                } 
                else{
                    have_bug = true;
                } 
            }
            printf("Scenario #%d:
    ", k);
            if(have_bug){
                printf("Suspicious bugs found!
    ");
            }
            else{
                printf("No suspicious bugs found!
    ");
            }
        }
    }
    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14482826.html
Copyright © 2011-2022 走看看