POJ2492 A Bug's Life

题目链接

POJ2492 A Bug's Life

题目描述

  • 有两种性别的虫子。它们只能不同性别间交配。给出一堆虫子的交配列表。判断是否满足只能在不同性别间交配的命题。

    解题思路

  • 利用带权并查集,把可以判断出性别关系的虫子放到同一集合中。
  • 在Merge()和GetRoot()函数中更新子结点与根节点的性别关系。
  • 性别关系类似于向量加减,可通过画向量图的方式计算结点间的关系。

    代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<stack>
using namespace std;
const int MAXN = 2010;
int par[MAXN];//par[i]是i的根节点 
int rea[MAXN];//rea[i]是i和根节点的关系,0是同性,1是异性 
int GetRoot(int a, int r); 
void Merge(int a, int b, int r);
bool Query(int a, int b);
int n, m;//n个虫子,m个操作 
int main()
{
    int k;
    scanf("%d", &k);
    int kase = 0;
    while(k--){
        ++kase;
        int i, r, x, y;
        bool flag = 0;
        scanf("%d%d", &n, &m);
        for(i = 0;i <= n; ++i){
            par[i] = i;
            rea[i] = 0;
        } 
        for(i = 0;i < m; ++i){
            scanf("%d%d", &x, &y);
            if(!Query(x, y)){
                Merge(x, y, 1);
            }
            else{
                if(rea[x] == rea[y]){
                    flag = 1;
                }
            }
        }
        printf("Scenario #%d:\n", kase);
        if(flag) printf("Suspicious bugs found!\n");
        else printf("No suspicious bugs found!\n");
        printf("\n");
    }
}
int GetRoot(int a)
{
    if(par[a] == a)
        return a;
    int pa = GetRoot(par[a]);
    rea[a] = (rea[par[a]] + rea[a])%2;
    par[a] = pa;
    return pa;
}
void Merge(int a, int b, int r)
{
    int pa = GetRoot(a);
    int pb = GetRoot(b);
    if(pa != pb){
        par[pb] = pa;
        rea[pb] = (rea[a] - r - rea[b] + 4) % 2;
    }
    return ;
}
bool Query(int a, int b)
{
    return GetRoot(a) == GetRoot(b);
}
上一篇:影音风暴-Ⅰ


下一篇:I'm still a child seeking for the naked truth of life.