-
K - Rochambeau
- POJ - 2912
- 题意:玩石头剪刀布游戏,有三类人,每一类只能出石头剪刀布的一种,有裁判,它可以属于任意一类判断,能否确定裁判
- 思路:枚举裁判,然后并查集判断,裁判由于可以任意出,所以可能属于任意一个集合,所以有裁判参与的会合不考虑,
- 然后并查集部分和食物链很相似。如果某个裁判那里出现了矛盾,则记录一下在哪出问题。
- 然后判断是否只有一个裁判没有出现问题。如果只有一个,说明可以确定,那么就是剩下的人出问题的最大值。
- 因为只有否定了其它所有人,才能确定。
-
#include<stdio.h> #include<cstring> #include<iostream> using namespace std; #define inf 0x3f3f3f3f #define maxn 3515 char str; int n,m,ans,a,b,id,ansid; struct edge { int u,v,o; } data[maxn]; struct node { int fa,val; } num[maxn]; void init() { for(int i=0; i<n; i++) { num[i].fa=i; num[i].val=0; } } int root(int x) { if(num[x].fa==x)return x; int temp=num[x].fa; num[x].fa=root(num[x].fa); num[x].val=(num[temp].val+num[x].val)%3; return num[x].fa; } int main() { while(scanf("%d%d",&n,&m)==2) { ans=-1; ansid=0; for(int i=1; i<=m; i++) { scanf("%d%c%d",&a,&str,&b); data[i].u=a; data[i].v=b; if(str=='=') data[i].o=0; else if(str=='<') data[i].o=2; else data[i].o=1; } for(int i=0; i<n; i++) { init(); bool flag=0; id=inf; for(int j=1; j<=m; j++) { if(data[j].u==i||data[j].v==i)continue; a=root(data[j].u); b=root(data[j].v); if(data[j].o==0) { if(a==b) { if(num[data[j].u].val!=num[data[j].v].val) { flag=1; id=min(id,j); } } else { num[b].fa=a; num[b].val=(num[data[j].u].val+3-num[data[j].v].val)%3; } } else if(data[j].o==1) { if(a==b) { if((num[data[j].v].val+3-num[data[j].u].val)%3!=1) { flag=1; id=min(id,j); } } else { num[b].fa=a; num[b].val=(num[data[j].u].val+4-num[data[j].v].val)%3; } } else { if(a==b) { if((num[data[j].v].val+3-num[data[j].u].val)%3!=2) { flag=1; id=min(id,j); } } else { num[b].fa=a; num[b].val=(num[data[j].u].val+2+3-num[data[j].v].val)%3; } } } if(flag==0&&ans==-1) ans=i; else if(flag==0) ans=-2; else ansid=max(ansid,id); } if(ans==-1)printf("Impossible\n"); else if(ans==-2)printf("Can not determine\n"); else printf("Player %d can be determined to be the judge after %d lines\n",ans,ansid); } return 0; }
K - Rochambeau POJ - 2912 -枚举+带权并查集
猜你喜欢
转载自blog.csdn.net/BePosit/article/details/84141478
今日推荐
周排行