poj 2912 rochambeau

这个题目并查集的意味还是比较浓厚的,刚开始纠结于里面的数是不是全是正的,其实不是是全体整数。

思路就是枚举谁是judge,然后有judge的当然不能用并查集找矛盾了。除了有judge的边不添加,当添加其他边出现矛盾时,这个假定的judge必然不是真正的judge。这个题目还要记录有几组可能的judge,并且如果只有一个可能还要输出最少多少行后能知道答案。后一个问题要求出所有的其他情况最少出错的行数,然后输出最大值即可。

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int father[505],relation[505];
struct node{
	int pre;
	int root;
	int g;
};
node sent[2005];
int find_ant(int x)
{
	if(x!=father[x])
	{
		int t=father[x];
		father[x]=find_ant(father[x]);
		relation[x]=(relation[x]+relation[t])%3;
	}
	return father[x];
}
void unin(int x,int y,int s)
{
	int x_x,y_y;
	x_x=find_ant(x);
	y_y=find_ant(y);
	father[x_x]=y_y;
	relation[x_x]=((relation[y]+s)%3+3-relation[x])%3;
}
int maxi(int a,int b)
{
	if(a>b)
		return a;
	return b;
}
int main()
{
	char re[20];
	int n,m,i,aim,countj,counter,j,sum,first,time,ans;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		gets(re);
		for(i=1;i<=m;i++)
		{
			gets(re);
			int length=strlen(re);
			sent[i].pre=0;
			aim=0;
			while(re[aim]!='<'&&re[aim]!='='&&re[aim]!='>')
			{
				if(re[aim]!=' ')
					sent[i].pre=sent[i].pre*10+(re[aim]-'0');
				aim=aim+1;
			}
			if(re[aim]=='<')
				sent[i].g=2;
			else if(re[aim]=='=')
				sent[i].g=0;
			else if(re[aim]=='>')
				sent[i].g=1;
			aim=aim+1;
			sent[i].root=0;
			while(aim<length)
			{
				if(re[aim]!=' ')
					sent[i].root=sent[i].root*10+(re[aim]-'0');
				aim=aim+1;
			}
			/*cout<<sent[i].pre<<" "<<sent[i].g<<" "<<sent[i].root<<endl;*/
		}
		countj=0;
		time=0;
		for(i=0;i<n;i++)
		{
			/*cout<<i<<" "<<n<<endl;*/
			counter=-1;
			for(j=0;j<n;j++)
			{
				father[j]=j;
				relation[j]=0;
			}
			for(j=1;j<=m;j++)
			{
				if(sent[j].pre==i||sent[j].root==i)
					continue;
				int x,y;
				x=find_ant(sent[j].pre);
				y=find_ant(sent[j].root);
				if(x==y)
				{
					if(((sent[j].g+relation[sent[j].root])%3)!=relation[sent[j].pre])
					{
						counter=j;
						break;
					}
				}
				else unin(sent[j].pre,sent[j].root,sent[j].g);
			}
			if(counter==-1)
			{
				countj=countj+1;
				ans=i;
				if(countj>1)
					break;	
			}
            time=maxi(time,counter);
			/*cout<<countj<<endl;*/
		}
		if(countj==0)
			cout<<"Impossible"<<endl;
		else if(countj>=2)
			cout<<"Can not determine"<<endl;
		else cout<<"Player "<<ans<<" can be determined to be the judge after "<<time<<" lines"<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值