前言:无主之地3优化堪忧,且价格偏高。想看新上映的柯南的电影
https://www.cnblogs.com/geloutingyu/p/6145706.html
题意为给定$n$个人玩剪刀石头布,给出$m$个输赢关系,其中除了一个裁判其他人都只会出一样的手势,问是否存在这样的裁判,若存在且能确定输出裁判编号和最少在第几轮确定,若不能确定是谁输出另外的字符串
维护关系使用并查集,但是对于裁判我们没法处理,如果先想简单版本没有裁判的话,我们无非是维护带边权/扩展域并查集看有没有冲突即可,结合数据范围,不如枚举裁判的编号,维护剩下人的关系,如果成立那么他可能是裁判
如果有多个符合条件的人那么我们无法判断是谁,根据样例也能看出来
最早判断出来的时间是其他$n-1$个人都被排除的时间,也就是这些有矛盾的关系中最晚的一个
具体边权之间的关系据说可以推出来(我没有
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> using namespace std; const int maxn=509; int n,m; int fa[maxn],d[maxn]; inline int find(int x){ if(x==fa[x])return x; int rt=find(fa[x]); d[x]=(d[x]+d[fa[x]])%3; return fa[x]=rt; } struct node{ int a,b,c; }q[2009]; bool pd(int a,int b,int c){ int aa=find(a),bb=find(b); if(aa==bb){ // if(d[a]==0){ // if(d[b]!=c)return 1; // } // else if(d[a]==1){ // if(abs(d[b]-1)!=c)return 1; // } // else{ // if(abs(d[b]-2)!=c)return 1; // } if((d[b]-d[a]+3)%3!=c)return 1; } else { fa[bb]=aa; // if(d[a]==0)d[bb]=c; // else{ // int fa=(d[a]+c)%3,fb=(d[b]+c)%3; // if(fa-fb==1)d[bb]=1; // else if(fa-fb==-1)d[bb]=2; // else d[bb]=0; // } d[bb]=(d[a]-d[b]+c+3)%3; } return 0; } int main(){ while(~scanf("%d%d",&n,&m)){ char c; for(int i=1;i<=m;i++){ scanf("%d%c%d",&q[i].a,&c,&q[i].b); if(c=='=')q[i].c=0; else if(c=='>')q[i].c=1; else q[i].c=2; } // for(int i=1;i<=m;i++)cout<<q[i].c<<endl; int tot=0,flg=1,mx=0,jud=0; for(int i=0;i<n;i++){//枚举裁判 flg=1; for(int j=0;j<n;j++)d[j]=0,fa[j]=j; for(int j=1;j<=m;j++){ if(q[j].a==i || q[j].b==i)continue;//排除裁判 if(pd(q[j].a,q[j].b,q[j].c)){ mx=max(j,mx); flg=0; break; } } if(flg){ tot++;jud=i; } } if(!tot)printf("Impossible\n"); else if(tot>1)printf("Can not determine\n"); else printf("Player %d can be determined to be the judge after %d lines\n",jud,mx); } }