【并查集】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!
");
        }
    }
}
作者:老干妈就泡面
本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/bjxqmy/p/14482826.html