题意:有三组小朋友在玩石头剪刀布,同一组的小朋友出的手势是一样的。这些小朋友中有一个是裁判,他可以随便出手势。现在给定一些小朋友的关系,问能否判断出裁判,如果能最早什么时候能够找到裁判。
思路:枚举每个小朋友,删除与这个小朋友有关的边,利用并查集判断是否有冲突,如果有冲突说明这个小朋友不能成为裁判,因为不可能有两个裁判。记录可能的裁判的数量,以及对应每个小朋友最早冲突的时间。
如果裁判的数量为1,很明显这个小朋友就是裁判,那么如何求得最早判定的时间?利用排除法,如果能够尽快的排除其他n-1个小朋友成为裁判的机会,那么答案就是max(err[i]),err[i]就是每个小朋友冲突的最早时间。
AC代码
#include <cstdio> #include <cmath> #include <cctype> #include <algorithm> #include <cstring> #include <utility> #include <string> #include <iostream> #include <map> #include <set> #include <vector> #include <queue> #include <stack> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") #define eps 1e-10 #define inf 0x3f3f3f3f #define PI pair<int, int> typedef long long LL; const int maxn = 500 + 5; struct node{ int par; int real; }a[maxn]; struct Edge{ int u, v, k; }b[maxn<<2]; void init(int n) { for(int i = 0; i < n; ++i) { a[i].par = i; a[i].real = 0; } } int find(int x) { if(a[x].par == x) return x; int par = find(a[x].par); a[x].real = (a[x].real + a[a[x].par].real) % 3; return a[x].par = par; } bool unionset(int x, int y, int r) { int rx = find(x), ry = find(y); if(rx == ry) { int rr = (3 - a[y].real + a[x].real) % 3; if(rr != r) return false; } else { //合并 a[rx].par = y; a[rx].real = (3 - a[x].real + r) % 3; } return true; } int main() { int n, m; while(scanf("%d%d", &n, &m) == 2) { getchar(); char ch; for(int i = 0; i < m; ++i) { scanf("%d", &b[i].u); while(ch = getchar()) { if(ch == '=' || ch == '>' || ch == '<') { if(ch == '=') b[i].k = 0; else if(ch == '>') b[i].k = 1; else b[i].k = 2; break; } } scanf("%d", &b[i].v); //printf("%d %d %d\n", b[i].u, b[i].k, b[i].v); } int err = 0, flag, cnt = 0, judge; for(int i = 0; i < n; ++i) { //枚举裁判 init(n); int flag = 1; for(int j = 0; j < m; ++j) { int u = b[j].u, v = b[j].v; if(u == i || v == i) continue; if(!unionset(u, v, b[j].k)) { err = max(err, j+1); flag = 0; break; } } if(flag) { ++cnt; judge = i; } } if(cnt == 0) printf("Impossible\n"); else if(cnt >= 2) printf("Can not determine\n"); else printf("Player %d can be determined to be the judge after %d lines\n", judge, err); } return 0; }
如有不当之处欢迎指出!