K - Rochambeau POJ - 2912 -枚举+带权并查集

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

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/84141478