poj - 2912 枚举+种类并查集

题意:多个人玩石头剪刀布,每个人提前选定了自己出哪个手势,而其中有一种特殊的人他可以随意出什么手势,问是否能够从给出的一系列石头剪刀布游戏中判断出哪个是特殊的,可以从第几局游戏中判断出来。

定义0, 1, 2为三种手势,枚举每一个人,对于这个人不进行并查集操作,看剩下的会不会有矛盾,没有的话就可能是。局数就是枚举其他所有人出现矛盾的游戏场次的最大值,因为只有否定完其他所有人才能确定这个人是特殊的。

注意输入那个字符。。。。。。

链接:poj 2912

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <vector>
#include <sstream>
#define ll long long

using namespace std;

const int maxn = 2000 + 10;
const int maxm = 1000000 + 10;
const int inf = 0x3f3f3f3f;

int fa[maxn];
int r[maxn];
int error[maxn];

int n, m, k;

struct node {
    int a, b, c;
}q[maxn];

void init() {
    for(int i = 0; i < n; i++) {
        fa[i] = i;
        r[i] = 0;
    }
}

int getf(int x) {
    if(x != fa[x]) {
        int rt = fa[x];
        fa[x] = getf(fa[x]);
        r[x] = (r[x] + r[rt]) % 3;
    }
    return fa[x];
}


int main()
{
    int kcase = 0;
    int T;
    int a, b;
    init();
    int flag = 1;
    while(~scanf("%d %d", &n, &m)) {
        char c;
        for(int i = 0; i < m; i++) {
            scanf("%d", &q[i].a);
            c = getchar();
            while(c != '=' && c != '<' && c != '>') c = getchar();
            if(c == '=') q[i].c = 0;
            else if(c == '<') q[i].c = 1;
            else q[i].c = 2;
            scanf("%d", &q[i].b);
        }
        /*for(int i = 0; i < m; i++) {
            printf("%d %d %d\n", q[i].a, q[i].c, q[i].b);
        }*/
        memset(error, -1, sizeof(error));
        for(int i = 0; i < n; i++) {
            init();
            for(int j = 0; j < m; j++) {
                if(q[j].a == i || q[j].b == i) continue;
                int ra = getf(q[j].a);
                int rb = getf(q[j].b);
                if(ra == rb) {
                    if(r[q[j].b] != (r[q[j].a] + q[j].c) % 3) {
                        error[i] = j + 1;
                        break;
                    }
                }
                else {
                    fa[rb] = ra;
                    r[rb] = ((r[q[j].a] + q[j].c - r[q[j].b]) % 3 + 3) % 3;
                }
            }
        }
        int cnt = 0;
        int a1, a2 = 0;
        for(int i = 0; i < n; i++) {
            if(error[i] == -1) {
                cnt++;
                a1 = i;
            }
            if(error[i] > a2) a2 = error[i];
        }
        if(!cnt) printf("Impossible\n");
        else if(cnt > 1) printf("Can not determine\n");
        else printf("Player %d can be determined to be the judge after %d lines\n", a1, a2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/C_CQQ/article/details/80070786