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; }