题目大意是有人要调查虫子是否在已知的条件下没有出现同性恋的。
输入第一行代表输入组个数,然后就是每一组数据都是包含虫子总数和实验的案例。
接下来每个案例两个数字,代表对应两个虫子可以交配。
最后输出是否有同性恋的虫子。
并查集思路如下:
假设两个虫子编号是x和y,虫子总数是n,那么我们把x和y+n,以及x+n和y归为一类,简单来说就是开大一倍数组,记录虫子的性别互斥的关系,接下来如果存在一个z,x和y都可以和z交配,那么就会在并查集里边把x和y连接起来。
准确说,如果先输入x和z,那么在输入y和z的时候,会发现y和z在同一个并查集里边,因为x和z+n连接,x+n和z连接,然而x+n是和y连接的。以此来判断是否有同性恋。
代码如下所示:
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<string>
#include<iostream>
#include<ctime>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int MAXN = 2005;
int s[MAXN*2], ok[MAXN*2];
int n,m,x,y;
void init_s(){
for (int i = 1; i <= 2*n; ++i) {
s[i]=i;
}
}
int find_s(int x){
if (x!=s[x]) s[x] = find_s(s[x]);
return s[x];
}
bool same(int x, int y){
return find_s(x)== find_s(y);
}
void union_s(int x,int y){
x = find_s(x);
y = find_s(y);
if (x!=y) {
s[x]=s[y];
}
}
int main() {
int total;
bool flag=false;//有同性恋则是true
scanf("%d",&total);
for (int i = 1; i <= total; ++i) {
flag=false;
scanf("%d %d",&n,&m);
init_s();
for (int k = 0; k < m; ++k) {
scanf("%d %d",&x,&y);
if (flag) continue;
if (same(x,y)){
flag=true;
continue;
}
union_s(x,y+n);
union_s(x+n,y);
}
if (flag){
printf("Scenario #%d:\nSuspicious bugs found!\n\n",i);
}else{
printf("Scenario #%d:\nNo suspicious bugs found!\n\n",i);
}
}
return 0;
}