Poj 2492 Cf 100923这辈子都学不会的带权并查集(种类并查集篇章)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/passer__/article/details/81976654

POj2492:http://poj.org/problem?id=2492

题意:给你n个虫子,有个人给你m对匹配关系,问你是否出现一对都是同性的情况。

思想:带权并查集数组出现每个的性别,即非0即1,如果都在一个块里面,判断他们的号是否相同,相同就不行,如果不在一个块里,那么就连接2个块,那么就更改某一个的原来的头的性别,然后下次用的时候更新下即可。

至于为何这样去更改原来父亲节点的权值,可以自己去算一下4种可能,发现就是这样。

#include<stdio.h>
int fa[2005];
int sum[2005]; 
int find(int x)
{
	if(x==fa[x])
		return x;
	int fx=fa[x];
	fa[x]=find(fa[x]);
	sum[x]=(sum[x]+sum[fx])%2;//连接之后更新关系 从后往前 
	return fa[x];
}
int main()
{
	int t;
	scanf("%d",&t);
	for(int Case=1;Case<=t;Case++)
	{
		int n,m,flag;
		flag=1;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++)
		{
			fa[i]=i;
			sum[i]=0;
		}
		for(int i=0;i<m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			if(flag==0)//已经错了 
				continue;
			int fx=find(u);
			int fy=find(v);
			if(fx==fy)//在一个链里面 
			{
				if((sum[u]+sum[v])%2==0)//说明在一起的而且是一个种类 
					flag=0;
			} 
			else//2个链 
			{
				fa[fx]=fy;
				sum[fx]=(sum[u]+sum[v]+1)%2; 
			}
		}
		printf("Scenario #%d:\n",Case);
		if(flag)
			printf("No suspicious bugs found!\n");
		else
			printf("Suspicious bugs found!\n");
		printf("\n");
	}
	return 0;
} 

codeforces:http://codeforces.com/gym/100923/problem/H

题意:已知有n个战士,分属于两个红、蓝阵营,现输入m条敌对关系,当本条关系信息与之前的真的关系信息冲突,则认为本条关系信息为假(即先输入的敌对关系优先为真)。

#include<stdio.h>
int fa[200005];
int sum[100005]; 
int find(int x)
{
	if(x==fa[x])
		return x;
	int fx=fa[x];
	fa[x]=find(fa[x]);
	sum[x]=(sum[x]+sum[fx])%2;//连接之后更新关系 从后往前 
	return fa[x];
}
int main()
{
	int t;
	freopen("meciul.in", "r", stdin);
    freopen("meciul.out", "w", stdout);
	scanf("%d",&t);
	for(int Case=1;Case<=t;Case++)
	{
		int n,m,flag;
		flag=1;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++)
		{
			fa[i]=i;
			sum[i]=0;
		}
		for(int i=0;i<m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			int fx=find(u);
			int fy=find(v);
			if(fx==fy)//在一个链里面 
			{
				if((sum[u]+sum[v])%2==0)//说明在一起的而且是一个种类 
					printf("NO\n");
				else
					printf("YES\n");
			} 
			else//2个链 
			{
				printf("YES\n");
				fa[fx]=fy;
				sum[fx]=(sum[u]+sum[v]+1)%2; 
			}
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/passer__/article/details/81976654