poj 2912 并查集(食物链加强版)

题目:给出n个人玩剪刀石头布的游戏,其中有一个人是裁判,剩下的人分为3组,每一组的人只出某一种手型,裁判可以任意出。问是否能判断出哪个人是裁判

链接:点我

 

分分钟看吐血,先把食物链看懂吧

 

枚举裁判,然后并查集判断

裁判由于可以任意出,所以可能属于任意一个集合,所以有裁判参与的会合不考虑,然后并查集部分和食物链很相似。

如果某个裁判那里出现了矛盾,则记录一下在哪出问题。

然后判断是否只有一个裁判没有出现问题。如果只有一个,说明可以确定,那么就是剩下的人出问题的最大值。因为只有否定了其它所有人,才能确定

 

枚举裁判,然后并查集判断

 

裁判由于可以任意出,所以可能属于任意一个集合,所以有裁判参与的会合不考虑,然后并查集部分和食物链很相似。

 

如果某个裁判那里出现了矛盾,则记录一下在哪出问题。

 

然后判断是否只有一个裁判没有出现问题。如果只有一个,说明可以确定,那么就是剩下的人出问题的最大值。因为只有否定了其它所有人,才能确定

枚举+并查集
枚举每一个裁判,看有没有不出错的
如果没有,说明是Impossible
如果有超过一个,那么就是Can not determine
如果只有一个,那么输出其他出错的位置的最大值

 

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 #include <iostream>
  5 using namespace std;
  6 const int MAXN=510;
  7 const int MAXM=2010;
  8 struct Node
  9 {
 10     int u,v;
 11     int re;
 12 }node[MAXM];
 13 int F[MAXN];
 14 int val[MAXN];
 15 int find(int x)
 16 {
 17     if(F[x]==-1)return x;
 18     int tmp=find(F[x]);
 19     val[x]+=val[F[x]];
 20     val[x]%=3;
 21     return F[x]=tmp;
 22 }
 23 char str[30];
 24 int main()
 25 {
 26     int n,m;
 27     int u,v;
 28     while(scanf("%d%d",&n,&m)==2)
 29     {
 30         gets(str);
 31         for(int i=0;i<m;i++)
 32         {
 33             //scanf("%s",&str);
 34             gets(str);
 35             int t=0;
 36             int len=strlen(str);
 37             for(t=0;t<len;t++)
 38               if(str[t]=='>'||str[t]=='='||str[t]=='<')
 39                 break;
 40             u=0;
 41             for(int j=0;j<t;j++)
 42             {
 43                 u*=10;
 44                 u+=str[j]-'0';
 45             }
 46             v=0;
 47             for(int j=t+1;j<len;j++)
 48             {
 49                 v*=10;
 50                 v+=str[j]-'0';
 51             }
 52             node[i].u=u;
 53             node[i].v=v;
 54             if(str[t]=='=')node[i].re=0;
 55             else if(str[t]=='<')node[i].re=1;
 56             else node[i].re=2;
 57         }
 58         int ansi;
 59         int anst=0;
 60         int t0=0;//不矛盾的个数
 61         for(int i=0;i<n;i++)
 62         {
 63             memset(F,-1,sizeof(F));
 64             memset(val,0,sizeof(val));
 65             int ff=-1;
 66             for(int j=0;j<m;j++)
 67             {
 68                 if(node[j].u==i || node[j].v==i)continue;
 69                 u=node[j].u;
 70                 v=node[j].v;
 71                 int t1=find(u);
 72                 int t2=find(v);
 73                 if(t1==t2)
 74                 {
 75                     if(val[v]!=(val[u]+node[j].re)%3)
 76                     {
 77                         ff=j+1;
 78                         break;
 79                     }
 80                 }
 81                 else
 82                 {
 83                     F[t2]=t1;
 84                     val[t2]=val[u]-val[v]+node[j].re;
 85                     val[t2]=(val[t2]+3)%3;
 86                 }
 87             }
 88             if(ff==-1)
 89             {
 90                 ansi=i;
 91                 t0++;
 92             }
 93             else anst=max(anst,ff);
 94         }
 95         if(t0==0)printf("Impossible\n");
 96         else if(t0>=2)printf("Can not determine\n");
 97         else
 98            printf("Player %d can be determined to be the judge after %d lines\n",ansi,anst);
 99     }
100     return 0;
101 }

 

posted @ 2015-05-08 23:05  miao_a_miao  阅读(140)  评论(0编辑  收藏  举报