A Bug‘s Life (种类并查集)

A Bug’s Life

问题描述

问题背景
霍普教授正在研究一种罕见的虫子的性行为。他假设它们有两种不同的性别,而且它们只与异性的虫子互动。在他的实验中,各个虫子和它们的互动都很容易识别,因为它们的背上印有数字。

问题
给出一个虫子相互作用的清单,决定这个实验是否支持他的假设,即有两种性别,没有同性恋的虫子,或者是否包含一些可以证明的虫子相互作用。

输入
输入的第一行包含方案的数量。每个场景开始都有一行给出虫子的数量(至少一个,最多2000个)和互动的数量(最多1000000),用一个空格隔开。在接下来的几行中,每个交互以两个不同的错误编号的形式给出,并以一个空格隔开。虫子是连续编号的,从1开始。

输出
每个场景的输出是包含 "场景#i: "的一行,其中i是场景的编号,从1开始,后面有一行是 "没有发现可疑的虫子!"如果实验与他关于虫子性行为的假设一致,或者 "发现可疑的虫子!"如果霍普教授的假设肯定是错误的。

输入样本

2
3 3
1 2
2 3
1 3
4 2
1 2
3 4

输出样本
情景#1。
Suspicious bugs found!

情景#2。
No suspicious bugs found!

温馨提示
巨大的输入,建议使用scanf。

思路

种类并查集的通解,开n倍的数组处理同性和异性的集合
1 2
2 3
1 3
(1,2)是异性,(2,3)是异性,1,3就是在一个集合则是同性
按理来说(1,3)应该是同性,
题中却给出(1,3)也是异性,此时就自相矛盾了
开两倍数组,(1,2)是异性—>merge(1,2+3)是同性
(2,1)是异性—>merge(2,1+3)是同性

AC代码

#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
#define IOS ios::sync_with_stdio(false);
typedef long long ll;
typedef pair<int,int> p;
const int MAXN=2005;;
const int INF=0x3f3f3f3f;
int pre[MAXN*2];
void init(int n){
	for(int i=0;i<n;i++)
		pre[i]=i;
}
int find(int x){
	if(x==pre[x])
		return x;
	return pre[x]=find(pre[x]);
}
void merge(int x,int y){
	x=find(x);
	y=find(y);
	if(x!=y)
		pre[x]=y;
}
int main(){
	int T,n,m,a,b,flag;;
	scanf("%d",&T);
	for(int i=1;i<=T;++i){
		init(MAXN<<1);
		flag=0;
		scanf("%d%d",&n,&m);
		while(m--){
			scanf("%d%d",&a,&b); // 给定一组异性关系
			if(find(a) == find(b)) // 根据前面的推导发现应该是同性
				flag=1; // 自相矛盾
			else // 建立异性关系
			{
				merge(a,b+n); 
				merge(b,a+n);
			}
		}
		if(flag)
			printf("Scenario #%d:\nSuspicious bugs found!\n",i);
		else
			printf("Scenario #%d:\nNo suspicious bugs found!\n",i);
		if(i<T)
			printf("\n");	
	}
    return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值