poj2912 Rochambeau---枚举+并查集

题目链接:https://vjudge.net/problem/POJ-2912

注意到n,m都很小,所以可以枚举每一个人,判断他能否为裁判(如果不考虑这个人参与的胜负关系,其他的胜负关系没有矛盾,则他可能为裁判)。判断是否矛盾可以用并查集,这个过程和poj1182基本一样。最后的问题是判断最早在第几行可以确定,如果确定只有一个人是裁判,那么其他人必然都不是,所以其他n-1个人出现矛盾的最大行数就是答案

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct st{int x,y; char ch;}r[2010];
int v[510],fa[510],n,m,i,k;

int find(int x){
	if (fa[x]!=x){
	  int t=fa[x];
	  fa[x]=find(fa[x]);
	  v[x]=(v[x]+v[t])%3;
	} 
	return fa[x];
}

int main(){
	while (~scanf("%d%d",&n,&m)){
	  for (i=1;i<=m;i++) scanf("%d%c%d",&r[i].x,&r[i].ch,&r[i].y);
	  int num,step,f,p; num=step=0;
	  for (k=0;k<n;k++){
	  	for (i=0;i<n;i++) fa[i]=i; 
	    memset(v,0,sizeof(v)); f=0;
		int d1,d2; 
	  	for (i=1;i<=m;i++){
	  	  if (r[i].x==k||r[i].y==k) continue;
	  	  if (r[i].ch=='=') d1=0; 
	  	  else if (r[i].ch=='<') d1=1; else d1=2;
		  int fx=find(r[i].x); int fy=find(r[i].y);
		  if (fx==fy){
		  	d2=(v[r[i].x]-v[r[i].y]+3)%3;
		  	if (d1!=d2){ f=1; step=max(i,step); break;}
		  }	
		  else {
		  	fa[fx]=fy; v[fx]=(v[r[i].y]+d1-v[r[i].x]+3)%3;
	      }
		}
		if (f==0) { p=k;num++;}
	  }
	  if (num>1) printf("Can not determine
");
	  else if (num==0) printf("Impossible
");
	  else printf("Player %d can be determined to be the judge after %d lines
",p,step);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/edmunds/p/13582960.html