POJ_1703_Find them_并查集

本文深入探讨并查集在解决黑社会组织关系鉴定问题的应用,通过定义循环数组模式,实现灵活判断组织归属,提供了解决实际问题的高效算法策略。

努力,努力,再努力。


题意:

一个城市里有两帮黑社会,一共n个人,从1-n编号,需要你来鉴定他们之间的关系,提供的信息形式为某两个人不是一个组织的,在线提问某两个人的关系,要求确认在一个组织或确认不在一个组织或现在无法确认。



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."

并查集的小进阶。并查集可以快速查询、插入某两个元素在一个集合的信息,但是这个集合的定义是我们自己定的,并不是只能表示这两个元素属于同一个组织这样的意思,并查集的题目往往需要维护多种类型的关系,而这些关系之间又是相互影响的,这时就可以用循环数组的模式,定义在不同循环节中的两个元素在一个集合中代表什么含义。

具体到这道题,我们定义对任意两个元素a, b,如果a和b+n或者a+n和b在一个集合中(即不再同一个循环节的两个元素在一个集合中),说明a和b不属于一个组织,这样的话就能很好的完成a和b不再一个组织,b和c不在一个组织,则a和c在一个组织这样的一个效果,其实是利用了循环数组的特点。


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 100010
int father[mxn<<1];
int n,m;
int find(int x){
	return father[x]==x ? x : father[x]=find(father[x]);
}
void uni(int x,int y){
	father[find(x)]=find(y);
}
bool same(int x,int y){
	return find(x)==find(y);
}
void init(){
	for(int i=1;i<=2*n;++i)	father[i]=i;
}
int main(){
	int cs,a,b;
	char op;
	scanf("%d",&cs);
	while(cs--){
		scanf("%d%d",&n,&m);
		init();
		for(int i=0;i<m;++i){
			getchar();
			scanf("%c%d%d",&op,&a,&b);
			if(op=='A'){
				if(same(a,b)||same(a+n,b+n))
					puts("In the same gang.");
				else if(same(a,b+n)||same(a+n,b))
					puts("In different gangs.");
				else	puts("Not sure yet.");
			}
			else{
				uni(a,b+n);
				uni(a+n,b);
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值