[kuangbin带你飞]专题五 并查集 K POJ 2912

来源:互联网 发布:centos设置ip地址 编辑:程序博客网 时间:2024/06/04 23:30

题目地址:https://vjudge.net/contest/66964#problem/K

思路:kuangbin的题解

枚举裁判,然后并查集判断
裁判由于可以任意出,所以可能属于任意一个集合,所以有裁判参与的会合不考虑,然后并查集部分和食物链很相似。
如果某个裁判那里出现了矛盾,则记录一下在哪出问题。
然后判断是否只有一个裁判没有出现问题。如果只有一个,说明可以确定,那么就是剩下的人出问题的最大值。因为只有否定了其它所有人,才能确定。

PS:这题写的好迷,我完全是按照之前的食物链写的并查集,就是wa。然后交换了一下判断是否符合时的p,q就ac了,什么鬼……

再PS:原来是我之前并起来的时候也写反了……果然思维还是混乱啊……

AC代码:

#include<iostream>#include<vector>#include<cstdio>#include<cmath>using namespace std;const int maxn=505;int fa[maxn];int sum[maxn];int n,m;struct pos{    int u,v,w;}E[maxn*4];int find(int p){    if(p==fa[p])        return p;    int old=fa[p];    fa[p]=find(fa[p]);    sum[p]=(sum[p]+sum[old])%3;    return fa[p];}int main(){    while(~scanf("%d %d",&n,&m))    {    for(int i=0;i<m;i++)    {    char c;    scanf("%d%c%d",&E[i].u,&c,&E[i].v);    //printf("%c\n",c);    if(c=='=')        E[i].w=0;    else if(c=='>')        E[i].w=2;    else if(c=='<')        E[i].w=1;    }    int ans=0,ansi=0,t=0;    for(int i=0;i<n;i++)    {        for(int j=0;j<=n;j++)        {            fa[j]=j;            sum[j]=0;        }        int bug=-1;        for(int j=0;j<m;j++)        {            int p=E[j].u,q=E[j].v;            int s=E[j].w;            if(p==i || q==i)                continue;            int fp=find(p);            int fq=find(q);            if(fp==fq)            {                if(sum[q]!=(s+sum[p])%3)                {                   bug=j+1;                    break;                }            }            else            {                fa[fq]=fp;                sum[fq]=(s+sum[p]-sum[q]+3)%3;            }        }        if(bug==-1)        {            t++;            ans=i;        }        else        {            ansi=max(ansi,bug);        }    }    if(t==0)        printf("Impossible\n");    else if(t>1)        printf("Can not determine\n");    else        printf("Player %d can be determined to be the judge after %d lines\n",ans,ansi);    }}


0 0