pku2192(并查集+枚举)

这题的话,跟食物链很相识,也是有三类,所以那个公式的话,还是一样的

题意是要找出里面唯一的一个judge,judge的特别就是他没有固定属于哪一类,所以只能枚举每一个人当judge的情况了

满足是唯一的judge的条件:

1)当然就是枚举完所有人,只有一个的时候,那就是唯一的了;

2)当此人是judge时,所有语句都成立,即不发生冲突

在这里题目还要出输出,在第几行判断该人是judge的,这个也蛮好理解的,此人之前的所有人作为judge时出现矛盾的行数的最大值就是就是我们判断的依据,

其实也可以这样想,判断当前面所以人不能成为judge的行数的最大,就是我们判断此人为judge的行数

当不止一个人可以成为judge是,输出Can not determine

当所有人都不能成为judge是,输出Impossible

#include<stdio.h>
#define MAXN 510
int f[MAXN],r[MAXN];
int a[2010],b[2010];
int find(int x)
{
	if(x==f[x])
		return f[x];
	int t=find(f[x]);
	r[x]=(r[x]+r[f[x]])%3;
	f[x]=t;
	return f[x];
}
int Union(int x,int y,int d)
{
	int a=find(x);
	int b=find(y);
	if(a==b)
	{
		if((r[x]+d)%3==r[y])
			return 1;
		else return 0;
	}
	else 
	{
		f[b]=a;
		r[b]=(r[x]-r[y]+d+3)%3;
	}
	return 1;
}
int main()
{
	int n,m,i,j,flag,num,d,max,k;
	char c[2001];
	while(scanf("%d %d",&n,&m)!=EOF)
	{
    	for(j=1;j<=m;j++)
			scanf("%d%c%d",&a[j],&c[j],&b[j]);
		num=max=0;
		for(i=0;i<n;i++)
		{
			for(k=0;k<n;k++)//初始化
			{
				f[k]=k;
				r[k]=0;
			}
			for(j=1;j<=m;j++)
			{
				if(a[j]==i||b[j]==i)//当我们以i为judge时,输赢都无所谓,所以不合并,应该说是不能合并
					continue;
				if(c[j]=='=')
					d=0;
				else if(c[j]=='<')
					d=1;
				else d=2;
				if(Union(a[j],b[j],d)==0)
					break;
			}
			if(j==m+1)//所有语句都正确
			{
					num++;
					flag=i;
			}
			else 
			{
				if(j>max)
					max=j;
			}//
			if(num>=2)
				break;
		}
		if(num==0)
			printf("Impossible\n");
		else if(num==1)
			printf("Player %d can be determined to be the judge after %d lines\n",flag,max);
		else printf("Can not determine\n");
	}
	return 0;
}
posted @ 2011-05-12 12:23  枕边梦  阅读(193)  评论(0编辑  收藏  举报