题目链接
题意
剪刀石头布,给定关系,n个人有一个人是法官,可以随便出。关系不一定合法,需要你判断:这些关系是否是合法的(有且仅有一个法官),如果合法那么谁是法官,在第几个关系后可以找出法官
思路
先离线操作记录关系,枚举每一个人当作法官,有关法官的关系不记录,看是否存在冲突,如果存在说明这人不是法官,记录冲突发生的位置。枚举完后找一下一共几个人可以当法官,如果没有或者有多个说明关系有问题,否则取冲突位置最大值,即为可以找到法官的位置
代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;
typedef long long ll;
const int maxn=600;
const int inf=0x3f3f3f3f;
int fa[maxn];
int va[maxn];
bool ju[maxn];
int bug[maxn];
int n,m;
struct Node{
int u,v;
char ch;
}node[maxn*5];
void init(){
for(int i=0;i<maxn;i++){
va[i]=0;
fa[i]=i;
}
}
int find(int x){
if(x==fa[x])
return x;
int t=find(fa[x]);
va[x]+=va[fa[x]];
va[x]%=3;
return fa[x]=t;
}
void unite(int x,int y,int z){
int fx=find(x),fy=find(y);
if(fx==fy)
return ;
fa[fx]=fy;
va[fx]=va[y]+z-va[x]+3;
va[fx]%=3;
}
int main(){
IOS
while(cin>>n>>m){
for(int i=1;i<=m;i++)
cin>>node[i].u>>node[i].ch>>node[i].v;
memset(ju,0,sizeof ju);
memset(bug,0,sizeof bug);
for(int j=0;j<n;j++){
init();
for(int i=1;i<=m;i++){
int u,v,w;
char ch;
u=node[i].u,v=node[i].v,ch=node[i].ch;
if(u==j||v==j)
continue;
if(ch=='>')
w=2;
else if(ch=='<')
w=1;
else
w=0;
int fu=find(u),fv=find(v);
if(fu!=fv)
unite(u,v,w);
else{
if(va[u]==(va[v]+w)%3)
continue;
else{
ju[j]=1;
bug[j]=i;
break;
}
}
}
}
int sp_child,max_bug=0,cnt=0;
for(int i=0;i<n;i++)
if(!ju[i]){
cnt++;
sp_child=i;
}
else
max_bug=max(max_bug,bug[i]);
if(cnt>1)
cout<<"Can not determine"<<endl;
else if(!cnt)
cout<<"Impossible"<<endl;
else
cout<<"Player "<<sp_child<<" can be determined to be the judge after "<<max_bug<<" lines"<<endl;
}
}