种类并查集

问题概述: 当地有两个黑帮,A a b表示询问a和b是否属于同一黑帮,D a b表示确定a和b属于不同黑帮,对于每次A

问,输出它们的关系,具体见样例(POJ1703)

输入样例:                         对应输出:

1                                       Not sure yet.

5 5                                    In different gangs.

A 1 2                                 In the same gang.

D 1 2

A 1 2

D 2 4

A 1 4


解析在代码中

#include<stdio.h>
int ufs[100005], rel[100005];		/* ufs[k]中存放的是k的根节点,rel[k]中存放的是k与ufs[k]的关系,0表示两者属于不同类,1表示属于同一类*/
int Find(int x)
{
	int temp;
	if(ufs[x]==x)
		return x;
	temp = Find(ufs[x]);			/*这个也一定要放在前面,和带权并查集一样*/
	rel[x] = (rel[x]+rel[ufs[x]]+1)%2;	/*如果x与旧祖先的关系和旧祖先与新祖先的关系都为1或0,则x与新祖先属于同一类,否则属于不同类*/
	return ufs[x] = temp;
}

int main(void)
{
	int T, a, b, m, n, i, t1, t2;
	char ch;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d", &n, &m);
		for(i=1;i<=n;i++)
			ufs[i] = i, rel[i] = 1;
		for(i=1;i<=m;i++)
		{
			scanf(" %c%d%d", &ch, &a, &b);
			t1 = Find(a);
			t2 = Find(b);
			if(ch=='A')
			{
				if(t1==t2)	/*如果它们的祖先是同一个,则他们的关系就已经确定*/
				{
					if(rel[a]==rel[b])
						printf("In the same gang.\n");
					else
						printf("In different gangs.\n");
				}
				else
					printf("Not sure yet.\n");
			}			/*PS:题目中不会有不合法的输入*/
			else
			{
				if(t1!=t2)	/*如果他们的关系还没有确定*/
				{
					ufs[t1] = t2;		/*连接a和b的祖先t1和t2,其中t2是t1的祖先*/
					rel[t1] = (rel[a]+rel[b])%2;	/*确认t2和t1的关系*/
				}
			}
		}
	}
	return 0;
}


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值