您的位置:首页 > 其它

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

2016-10-18 21:04 405 查看
题目地址: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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: