POJ 2492

POJ 2492

[题目大意]

詹姆斯莫里亚蒂教授认为一种稀有的虫子种间也有同性恋!在T种情况下,给出n只虫子(自动排序为第一到第n),并给出m组例子,每组例子种包含两个数据。表示这两只虫子会发生性交。问:根据这些数据能否判断出这种稀有的虫子中存在同性恋呢?

[核心要点]

最简单的单纯并查集问题。

[知识点]

并查集知识点不再这里赘述,请参考HDU 3088

[解法概述]

解法同HDU3833类似。

直接看unite()函数的解法。

 由上图可知,val[x] + val[b] = 1 + val[y]

val[x] = (val[y] + val[x] + 1) % 2;      (AC)

即val[b] 可看作val[x]与val[y]异或关系的逆(即同或),但cpp貌似没有同或运算符,用|显示WA。

需要写作rank[a]=!( rank[x] ^ rank[y]);   (AC)

[AC代码]

#include<iostream>
#include<cstdio>//scanf!!!

using namespace std;

#define N 2020

int par[N];
bool rank[N];//sexual orientation

int n,m;
int casenum;

void init( )
{
    for(int i=1;i<=n;i++)
    { 
        par[i]=i;
        rank[i]=0;
    }
}

int find(int n)
{
    
    if(par[n]==n)
        return n;
    int t=find(par[n]);
    rank[n]=(rank[n]+rank[par[n]])%2;
    par[n]=t;
    return par[n];
}

int  unite(int x,int y)
{
    
    int a=find(x);
    int b=find(y);
    if(a==b)
    {
        if(rank[x]==rank[y])
            return 1;
    }
    else 
    {
        par[a]=b;
        rank[a]=(rank[x]+rank[y]+1)%2;
    }
    return 0;
}


int main()
{
    cin >> casenum;
    int a,b;
    int flag;
    int cnt = 1;
    for(int i=1;i<=casenum;i++)
    {
    	
        flag=0;
        scanf("%d%d",&n,&m);
        
        init( );
        
        for(int j=1;j<=m;j++)
        {
            scanf("%d%d",&a,&b);
            if(unite(a,b))   flag=1;
        }
        if(flag==1)
            printf("Scenario #%d:\nSuspicious bugs found!\n\n",cnt++);
        else 
            printf("Scenario #%d:\nNo suspicious bugs found!\n\n",cnt++);


    }
    return 0;
}

 

posted @ 2018-08-07 21:39  ronnie14165  阅读(88)  评论(0编辑  收藏  举报