POJ 2912 Rochambeau(枚举+带权并查集)

来源:互联网 发布:学网店美工 编辑:程序博客网 时间:2024/05/16 10:35

题目链接:Rochambeau

题意:一堆人剪刀石头布,有一些人只会出剪刀,一些只会石头,一些只会布,然后有一个裁判可以随便出,给出比的情况,问能否确定裁判,如果可以找出裁判并输出哪条确定的

思路:带权并查集,先枚举裁判,然后去进行并查集,和食物链那题处理方法一样,最后判断能确定是不是1,如果是1就是能确定,那么确定位置为出现矛盾的最大位置

代码:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 505;const int M = 2005;int n, m, parent[N], rank[N], ans2;char str[105];struct C {    int a, b, d;} c[M];void tra(char *str, int num) {    int i = 0, len = strlen(str);    int sum = 0;    for (;i < len; i++) {if (str[i] >= '0' && str[i] <= '9')    sum = sum * 10 + str[i] - '0';if (str[i] == '<' || str[i] == '=' || str[i] == '>')    break;    }    c[num].a = sum;    if (str[i] == '<') c[num].d = 1;    else if (str[i] == '=') c[num].d = 0;    else c[num].d = 2;    i++;    sum = 0;    for (;i < len; i++) {if (str[i] >= '0' && str[i] <= '9')    sum = sum * 10 + str[i] - '0';    }    c[num].b = sum;}void init() {    for (int i = 0; i < n; i++) {parent[i] = i;rank[i] = 0;    }}int find(int x) {    if (x == parent[x])return x;    int px = find(parent[x]);    rank[x] = (rank[x] + rank[parent[x]]) % 3;    return parent[x] = px;}bool judge(int num) {    init();    for (int i = 0; i < m; i++) {if (c[i].a == num || c[i].b == num) continue;int a = c[i].a, pa = find(c[i].a);int b = c[i].b, pb = find(c[i].b);int d = c[i].d;if (pa == pb) {    if ((rank[a] - rank[b] + 3) % 3 != d) {ans2 = max(ans2, i + 1);return false;    }}else {    parent[pa] = pb;    rank[pa] = (rank[b] - rank[a] + 3 + d) % 3;}    }    return true;}int main() {    while (~scanf("%d%d%*c", &n, &m)) {ans2 = 0;for (int i = 0; i < m; i++) {    gets(str);    tra(str, i);}int num = 0, ans1 = 0;for (int i = 0; i < n; i++) {    if (judge(i)) {num++;ans1 = i;    }}if (num > 1)    printf("Can not determine\n");else if (num == 0)    printf("Impossible\n");else printf("Player %d can be determined to be the judge after %d lines\n", ans1, ans2);    }    return 0;}


0 0
原创粉丝点击