POJ 1703 - Find them, Catch them(种类并查集)

Find them, Catch them

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 61854 Accepted: 18743

Description

The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal belongs to. The present question is, given two criminals; do they belong to a same clan? You must give your judgment based on incomplete information. (Since the gangsters are always acting secretly.)

Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:

1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.

2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.
Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case begins with a line with two integers N and M, followed by M lines each containing one message as described above.
Output

For each message “A [a] [b]” in each case, your program should give the judgment based on the information got before. The answers might be one of “In the same gang.”, “In different gangs.” and “Not sure yet.”
Sample Input

1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
Sample Output

Not sure yet.
In different gangs.
In the same gang.

找到他们,抓住他们
时限: 1000MS 内存限制: 10000K
提交总数: 61854 接受: 18743
描述

塔杜市警察局决定结束这场混乱,因为发动了行动,扎根了该市的两个帮派,帮派龙和帮派蛇。但是,警察首先需要确定罪犯属于哪个帮派。现在的问题是,有两名罪犯。他们属于同一个氏族吗?您必须根据不完整的信息做出判断。(由于the徒总是在暗中行事。)

假设目前在塔都市有N(N <= 10 ^ 5)个罪犯,人数从1到N。当然,其中至少有一个属于Gang Dragon,并且相同帮蛇 您将依次收到M(M <= 10 ^ 5)条消息,有以下两种:

1. D [a] [b]
其中[a]和[b]是两名罪犯的号码,以及他们属于不同的帮派。

2. A [a] [b]
其中[a]和[b]是两名罪犯的人数。这需要您确定a和b是否属于同一个帮派。
输入值

输入的第一行包含一个整数T(1 <= T <= 20),即测试用例的数量。然后是T例。每个测试用例均以包含两个整数N和M的行开头,随后是M行,每行包含一个如上所述的消息。
输出量

对于每种情况下的每个消息“ A [a] [b]”,您的程序都应根据之前获得的信息做出判断。答案可能是“在同一帮派中”,“在不同帮派中”之一。和“不确定”。
样本输入
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
样本输出
Not sure yet.
In different gangs.
In the same gang.

题目链接

题目大意:在这座城里有两个帮派,给出 t 组测试样例,对于每组测试样例。有n个人和m条信息,接下来输入m行,A表示判断两者的关系,D表示两者不在同一帮派中。

解题思路:这是一道种类并查集,我们开一个两倍大小的数组,刚开始都初始化为-1,还是套用并查集的模板,碰到D时,传统并查集是合并,这个是拆除,怎么表示呢,我们有一个两倍大的数组,如果a和b不在同一帮派中,我们可以借用n,表示a 和b+n在同一帮派中,a+n和 b在同一帮派中,进行合并,碰到A时,判断a和b根节点的关系,如果同根则输出“In the same gang.”,不同根输出“In different gangs.”,如果都不是则输出“Not sure yet.”。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=1e5+50;
int f[2*_max];
int find(int x)//寻根
{
	if(f[x]!=-1)
	  return f[x]=find(f[x]);
	return x;  
}
void merge(int x,int y)//合并
{
	int t1=find(x);
	int t2=find(y);
	if(t1!=t2)
	  f[t2]=t1; 
}
bool check(int x,int y)//判关系
{
	int t1=find(x);
	int t2=find(y);
	if(t1==t2)
	  return true;
	return false;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		getchar();
		memset(f,-1,sizeof f);
		for(int i=1;i<=m;i++)
		{
			char ch;
			int a,b;
			scanf("%c%d%d",&ch,&a,&b);
			getchar();
			if(ch=='D')
			{
				merge(a,b+n);
				merge(a+n,b);
			}
			else
			{
				if(check(a,b))
				  cout<<"In the same gang."<<endl;
				else if(check(a,b+n))
				  cout<<"In different gangs." <<endl;
				else
				  cout<<"Not sure yet."<<endl;
			}
		}
	}
	//system("pause");
	return 0;
}
posted @ 2020-03-25 23:25  Hayasaka  阅读(65)  评论(0编辑  收藏  举报