题目链接:http://poj.org/problem?id=2912
题意:n个人玩猜拳,有且只有一个判官,n个人被分为三组,只能出特定的手势,判官可以随意出,找出谁是判官,无法确定输出
Can not determine,不可能存在这样的例子输出 Impossible,否者,输出谁是判官,最早可以在哪一行确定他是判官。
思路:并查集搞一搞,枚举每一个人。如果当第i个人是判官的时候,符合所有情况,说明第i个人可能是判官,如果有两个或以上的人可能是判官的时候输出Can not determine,如果枚举所有人都无法符合条件输出Impossible
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<iostream>
using namespace std;
struct node
{
int x,y,v;
node() {}
node(int _x,int _y,int _v): x(_x),y(_y),v(_v) {}
} A[2010];
int n,m,x,y,v,ans,lin;
int f[510],q[510];
char ch;
int found(int k)
{
if(k!=f[k])
{
int tem=f[k];
f[k]=found(f[k]);
q[k]=(q[k]+q[tem])%3;
}
return f[k];
}
int bcj(int i)
{
memset(q,0,sizeof(q));
for(int j=0; j<=n; j++) f[j]=j;
int tem,j;
for(j=0; j<m; j++)
{
x=A[j].x,y=A[j].y,v=A[j].v;
if(x==i||y==i) continue;
int p1=found(x),p2=found(y);
if(p1!=p2)
{
f[p1]=p2;
q[p1]=((v+q[y]-q[x])+3)%3;
}
else
{
if(v!=(q[x]-q[y]+3)%3)
{
tem=j+1;
break;
}
}
}
if(j==m)
{
if(ans==-1)
{
ans=i;
return 1;
}
return 0;
}
lin=max(lin,tem);
return 1;
}
int main()
{
L:
while(cin>>n>>m)
{
for(int i=0; i<m; i++)
{
cin>>x>>ch>>y;
v=ch=='='?0:ch=='<'?1:2;
A[i]=node(x,y,v);
}
ans=-1,lin=0;
for(int i=0; i<n; i++)
{
if(!bcj(i))
{
printf("Can not determine\n");
goto L;
}
}
if(ans==-1)
printf("Impossible\n");
else
printf("Player %d can be determined to be the judge after %d lines\n",ans,lin);
}
}
带权的运算那里把A【i】.x写成了x,卡了一个早上,MMP。