题目链接:http://poj.org/problem?id=2912
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1751
题意:有n个人玩石头剪刀布,所以会产生石头>剪刀,剪刀>布,布>石头,所以就产生了和食物链那题一样的关系;
枚举+关系并查集,枚举每个小孩为judge时的情况,若当前枚举情况下每个round都是正确的,则当前枚举编号可能是judge。
若只找到一个judge的可能,即为输出。若有多个就不确定了;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <map> #include <vector> using namespace std; typedef long long LL; #define N 2520 #define met(a, b) memset(a, b, sizeof(a)) int f[N], r[N], wrong[N]; int Find(int x) { int k = f[x]; if(x!=f[x]) { f[x] = Find(f[x]); r[x] = (r[x]+r[k])%3; } return f[x]; } struct node { int x, y, op; }a[N]; int main() { int n, m; while(scanf("%d %d", &n, &m)!=EOF) { met(a, 0); for(int i=1; i<=m; i++) { char ch; scanf("%d%c%d", &a[i].x, &ch, &a[i].y); if(ch == '=') a[i].op = 0; if(ch == '>') a[i].op = 1; if(ch == '<') a[i].op = 2; } for(int i=0; i<n; i++)///枚举裁判; { for(int j=0; j<n; j++) f[j] = j, r[j] = 0; wrong[i] = 0;///第i个人当裁判的时候在哪产生矛盾; for(int j=1; j<=m; j++) { if(a[j].x == i || a[j].y == i)continue; int x = a[j].x, y = a[j].y; int px = Find(x); int py = Find(y); if(px != py) { f[px] = py; r[px] = (r[y] + a[j].op - r[x] + 3)%3; } else if(px == py && (r[y]+a[j].op)%3 != r[x]) { wrong[i] = j; break; } } } int judge = 0, ans = 0, Index; for(int i=0; i<n; i++) { if(wrong[i] == 0) { judge++; Index = i; } ans = max(wrong[i], ans);///当其他的情况矛盾了,那么就是确定结果的时候; } if(judge == 1) printf("Player %d can be determined to be the judge after %d lines ", Index, ans); else if(judge == 0) printf("Impossible ");///没有产生; else printf("Can not determine ");///产生的不止一个,就是不确定; } return 0; }