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:
Suspicious bugs found!
",cnt++);
else
printf("Scenario #%d:
No suspicious bugs found!
",cnt++);
}
return 0;
}