POJ 2492 - A Bug's Life(种类并查集)

POJ 2492(种类并查集)

Time limit : 5000 ms
Memory limit : 32768 kB

小菜鸟的第一篇博客,呜呜呜,有不对的地方请指正(๑>؂<๑)

| Description |

Background
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs.

Problem
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.

| Input |

| The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one. |

| Output |

|The output for every scenario is a line containing “Scenario #i:”, where i is the number of the scenario starting at 1, followed by one line saying either “No suspicious bugs found!” if the experiment is consistent with his assumption about the bugs’ sexual behavior, or “Suspicious bugs found!” if Professor Hopper’s assumption is definitely wrong.|

题意概述

每个样例第一行给你n和m,n是小虫的个数,m是他们之间关系的数量,后面m+1行每行给出两个数字,代表小虫的序号。表示他们俩的性别是相反的,最后问你其中有没有冲突,比如一共三只小虫,给你三行
1 2
2 3
1 3
那么1和3一定是同性的,就产生了冲突。

解题思路

种类并查集典型题目。建立一个pre数组,开到n最大数的两倍。1–n表示一种性别,n+1 – 2n表示另一种性别。

bool same(int x,int y)
{
	return find(x)==find(y);
}

自定义函数,查询两只小虫的性别是否一样(是否在同一个集合中)

if(same(a,b) || same(a+n,b+n))
{
	flag=1;continue;
}
merge(a,b+n);
merge(a+n,b);

核心操作,如果两只小虫性别一样,标记一下,继续输入。如果不同,合并不同类。
注意:因为1~n和n+1 ~2n分别表示两个性别,所以a和b+n为相同性别,将他们合并,b和a+n也是如此。

AC代码:


#include<iostream>
using namespace std;
#define N 2005
int pre[N<<1];
int find(int x)
{
	if(x==pre[x])
		return x;
	return pre[x]=find(pre[x]);
}
void merge(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx==fy)
		return;
	pre[fx]=fy;
}
bool same(int x,int y)
{
	return find(x)==find(y);
}
int main()
{
	int n,m,t,a,b;
	scanf("%d",&t);
	for(int k=1;k<=t;k++)
	{
		int flag=0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n*2;i++)
			pre[i]=i;    /*初始化,刚开始各成一个集合*/
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			if(flag)
				continue;//如果已经发现有冲突存在,后面的就不用判断了 
			if(same(a,b) || same(a+n,b+n))
			{
				flag=1;continue;
			}
			merge(a,b+n);
			merge(a+n,b); //这两步合并相同性别的小虫 
		}
		printf("Scenario #%d:\n",k);
		if(flag)
			printf("Suspicious bugs found!\n\n");
		else
			printf("No suspicious bugs found!\n\n");//注意每个样例后额外有个换行。。。因为这个还wa了一次 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43693379/article/details/84591777