poj 2912 Rochambeau (带权并查集)
题解思路:
将所有条件存起来
枚举每个点是否为裁判,枚举时对涉及到此人的回合不进行操作,看是否出现矛盾,记录出现矛盾的回合。
如果仅有一点未出现矛盾,则此点为裁判,判断回合为max(出现矛盾的回合)
如果都出现矛盾 为Impossible的情况
其余为不可确认的情况
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
const int maxn=2e3+10;
using namespace std;
struct node{
int a,b,v;
}e[maxn];
int f[maxn],sum[maxn];
int root(int x)
{
if(f[x]==x) return x;
int rt=root(f[x]);
sum[x]=(sum[x]+sum[f[x]])%3;
return f[x]=rt;
}
int cul(char ch)
{
if(ch=='=') return 0;
if(ch=='<') return 1;
return 2;
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m))
{
int a,b,v,ok=0,ans=0,id=0;
char ch;
mem(e,0);
for(int i=1;i<=m;i++)
{
scanf("%d%c%d",&a,&ch,&b);
v=cul(ch);
e[i]=(node){a,b,v};
}
for(int k=0;k<n;k++)
{
for(int i=0;i<n;i++) f[i]=i;
mem(sum,0);
int i;
for(i=1;i<=m;i++)
{
a=e[i].a;
b=e[i].b;
v=e[i].v;
if(a==k||b==k) continue;
int x=root(a);
int y=root(b);
if(x!=y)
{
f[x]=y;
sum[x]=(v+sum[b]-sum[a]+3)%3;
}
else
{
if((sum[a]-sum[b]+3)%3!=v)
{
ans=max(ans,i);
ok++;
break;
}
}
}
if(i>m) id=k;
}
//cout<<ok<<endl;
if(ok==n-1) printf("Player %d can be determined to be the judge after %d lines\n",id,ans);
else if(ok==n) printf("Impossible\n");
else printf("Can not determine\n");
}
return 0;
}