poj 1703(种类并查集)

题目大意:在这个城市里有两个黑帮团伙,现在给出N个人,问任意两个人他们是否在同一个团伙
输入D x y代表x于y不在一个团伙里

输入A x y要输出x与y是否在同一团伙或者不确定他们在同一个团伙里


解题思路:这道题是一道很经典的种类并查集,除了有father[i]表示父亲节点外,还有rank[i]表示节点i与其父亲节点之间的关系,0表示是同类,1表示不同类。在路径压缩的时候要注意更新rank数组,这里的更新方法是向量偏移。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 100005;
int n,m,Fa[maxn],Rank[maxn];	//Rank[i]=1表示与祖先是不同的类,0表示相同类

int find(int x)
{   
	if(Fa[x] == x) return x;
	int tmp = Fa[x];
	Fa[x] = find(Fa[x]);
	Rank[x] = (Rank[x] + Rank[tmp]) % 2;
	return Fa[x];
}

int main()
{
	int t,a,b,x,y;
	char str[2];
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(int i = 1; i <= n; i++) Fa[i] = i, Rank[i] = 0;
		for(int i = 1; i <= m; i++)
		{
			scanf("%s",str);
			scanf("%d%d",&a,&b);
			x = find(a);
			y = find(b);
			if(str[0] == 'A')
			{
				if(x != y)
					printf("Not sure yet.\n");
				else
				{
					if(Rank[a] == Rank[b])
						printf("In the same gang.\n");
					else printf("In different gangs.\n");
				}
			}
			else
			{
				if(x == y) continue;
				Fa[y] = x;
				Rank[y] = (Rank[a] - Rank[b] + 1 + 2) % 2;
			}
		}
	}
	return 0;
}









你可能感兴趣的:(LCA)