POJ-2912-Rochambeau

Rochambeau

题目大意: N 个孩子们正在和你玩 “ 剪刀石头布 ” 游戏,其中一位是法官。其余的孩子分为三组(可能有一组是空的)。
你不知道谁是法官,也不知道孩子们是如何分组的。然后孩子们开始玩 \(Rochambeau\) 游戏 \(M\) 轮。每轮两个孩子被任意选择玩一次,你会被告知结果,但是你不知道孩子们做了什么手势。
同一组中的孩子会表现出相同的手势,不同的组会表现出不同的手势。
法官每次都会随机做出手势,因此没有人知道法官会做出什么手势。
比赛结束后,你能猜出谁是裁判吗?如果可以的话,你最早能在几轮之后找到法官

思路

并查集的拓展域或者边带权,十分类似于食物链这道题

每个人有三个部分:赢自己的人,自己赢的人,和自己出同样手势的人

如果这两个人 “ = ” ,就分别合并他们的三个集合
如果小于或者大于就像这样(统一把所有的 \(>\) 变成 \(<\) ):

int fa[N*3];//同族,输给了谁,赢了谁 
mer(a[j],b[j]+n*2),mer(a[j]+n,b[j]),mer(a[j]+n*2,b[j]+n);

枚举每个人为法官的时候,去掉所有与其相关的来判断有没有矛盾。如果有多个不产生矛盾的就为 Can not determine ,如果一个都没有就是 Impossible

至于找可判断出的行数就在判断过程中记录非裁判,出现矛盾的最大行数即为答案。

$Code$
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stdio.h>
using namespace std;

const int N=505,M=2005;
int fa[N*3],a[M],b[M],ed[M];//同族,输给了谁,赢了谁 
int n,m;

void unit(){
	for(int i=1;i<=n*3;++i)	fa[i]=i;
}
int fi(int x){
	if(fa[x]==x)	return x;
	return fa[x]=fi(fa[x]);
}
void mer(int x,int y){
	fa[fi(x)]=fi(y);
}

void sol(){
	for(int i=1;i<=m;++i){
		int x,y;char c;
		cin>>x>>c>>y;++x,++y;
		if(c=='>')	swap(x,y);
		a[i]=x,b[i]=y;
		if(c=='=')	ed[i]=0;
		else	ed[i]=1;//<
	}
	
	if(n==1){
		printf("Player 0 can be determined to be the judge after 0 lines\n");
		return;
	}
	
	int mrk=-1,ju=0,ans=-1;
	for(int i=1;i<=n;++i){
		unit();int cnt=0,is=0;
		for(int j=1;j<=m;++j){
			if(a[j]==i || b[j]==i)	continue;
			else{
				if(!ed[j]){
					if(fi(a[j])==fi(b[j]+n) || fi(a[j]+n)==fi(b[j])){
						is=-2,ans=max(ans,j);
						break;
					}
					mer(a[j],b[j]),mer(a[j]+n,b[j]+n),mer(a[j]+n*2,b[j]+n*2);
				}
				if(ed[j]){
					if(fi(a[j])==fi(b[j]) || fi(a[j]+n*2)==fi(b[j])){
						is=-2,ans=max(ans,j);
						break;
					}
					mer(a[j],b[j]+n*2),mer(a[j]+n,b[j]),mer(a[j]+n*2,b[j]+n);
				}
			}
		}
		if(is==-2)	continue;
		if(ju){
			mrk=-2;break;
		}
		ju=i;
	}
	
	if(ju && mrk!=-2)	printf("Player %d can be determined to be the judge after %d lines\n",ju-1,ans);
	else if(mrk==-2)	cout<<"Can not determine"<<endl;
	else	cout<<"Impossible"<<endl;
}

int main(){
	
	while(cin>>n>>m)	sol();
	
	return 0;
}
posted @ 2022-04-30 16:16  _yolanda  阅读(27)  评论(0编辑  收藏  举报