POJ - 2912 Rochambeau 枚举+并查集

题目链接

POJ-2912

题意

剪刀石头布,给定关系,n个人有一个人是法官,可以随便出。关系不一定合法,需要你判断:这些关系是否是合法的(有且仅有一个法官),如果合法那么谁是法官,在第几个关系后可以找出法官

思路

先离线操作记录关系,枚举每一个人当作法官,有关法官的关系不记录,看是否存在冲突,如果存在说明这人不是法官,记录冲突发生的位置。枚举完后找一下一共几个人可以当法官,如果没有或者有多个说明关系有问题,否则取冲突位置最大值,即为可以找到法官的位置

代码
#include<iostream>  
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;
	typedef long long ll;
	const int maxn=600;
	const int inf=0x3f3f3f3f;
	int fa[maxn];
	int va[maxn]; 
	bool ju[maxn];
	int bug[maxn];
	int n,m;
	struct Node{
		int u,v;
		char ch;
	}node[maxn*5];
	void init(){
		for(int i=0;i<maxn;i++){
			va[i]=0; 
			fa[i]=i;
		}
	}
	int find(int x){
		if(x==fa[x])
			return x; 
		int t=find(fa[x]);
		
		va[x]+=va[fa[x]]; 
		va[x]%=3;
		return fa[x]=t; 
	}
	void unite(int x,int y,int z){
		int fx=find(x),fy=find(y);
		if(fx==fy)
			return ;
		fa[fx]=fy;
		va[fx]=va[y]+z-va[x]+3; 
		va[fx]%=3;
	}
	int main(){
		IOS
		while(cin>>n>>m){
			for(int i=1;i<=m;i++)
				cin>>node[i].u>>node[i].ch>>node[i].v;
			memset(ju,0,sizeof ju);
			memset(bug,0,sizeof bug);
			for(int j=0;j<n;j++){
				init();
				for(int i=1;i<=m;i++){
					int u,v,w;
					char ch;
					u=node[i].u,v=node[i].v,ch=node[i].ch;
					if(u==j||v==j)
						continue;
					if(ch=='>')
						w=2;
					else if(ch=='<')
						w=1;
					else
						w=0;
					int fu=find(u),fv=find(v);
					if(fu!=fv)
						unite(u,v,w);
					else{
						if(va[u]==(va[v]+w)%3)
							continue;
						else{
							ju[j]=1;
							bug[j]=i;
							break;
						}
					}
				}
			}
			int sp_child,max_bug=0,cnt=0;
			for(int i=0;i<n;i++)
				if(!ju[i]){
					cnt++;
					sp_child=i;
				}
				else
					max_bug=max(max_bug,bug[i]);
			if(cnt>1)	
				cout<<"Can not determine"<<endl;
			else if(!cnt)
				cout<<"Impossible"<<endl;
			else
				cout<<"Player "<<sp_child<<" can be determined to be the judge after "<<max_bug<<" lines"<<endl;
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值