并查集------K - Rochambeau

N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is the judge. The rest children are divided into three groups (it is possible that some group is empty). You don’t know who is the judge, or how the children are grouped. Then the children start playing Rochambeau game for M rounds. Each round two children are arbitrarily selected to play Rochambeau for one once, and you will be told the outcome while not knowing which gesture the children presented. It is known that the children in the same group would present the same gesture (hence, two children in the same group always get draw when playing) and different groups for different gestures. The judge would present gesture randomly each time, hence no one knows what gesture the judge would present. Can you guess who is the judge after after the game ends? If you can, after how many rounds can you find out the judge at the earliest?

Input
Input contains multiple test cases. Each test case starts with two integers N and M (1 ≤ N ≤ 500, 0 ≤ M ≤ 2,000) in one line, which are the number of children and the number of rounds. Following are M lines, each line contains two integers in [0, N) separated by one symbol. The two integers are the IDs of the two children selected to play Rochambeau for this round. The symbol may be “=”, “>” or “<”, referring to a draw, that first child wins and that second child wins respectively.

Output
There is only one line for each test case. If the judge can be found, print the ID of the judge, and the least number of rounds after which the judge can be uniquely determined. If the judge can not be found, or the outcomes of the M rounds of game are inconsistent, print the corresponding message.

Sample Input
3 3
0<1
1<2
2<0
3 5
0<1
0>1
1<2
1>2
0<2
4 4
0<1
0>1
2<3
2>3
1 0
Sample Output
Can not determine
Player 1 can be determined to be the judge after 4 lines
Impossible
Player 0 can be determined to be the judge after 0 lines

这不是和那道食物链那道题完全一样吗,都是三组形成一个环,可以直接套公式:r[x]=(r[y]-r[x]+d-1+3)%3(1<=d<=3),用带权并查集解决。。。。菜。。。。居然没想到,其实题意读的不是很懂,。。
感觉这种找矛盾,有制约的得用带权并查集
题意:找出judge,这么多孩子中只有judge不满足这样的制约,所以只有judge那会出现矛盾点,找出judge,如果judge有多个,输出Can not determine,如果找不到judge,输出Impossible,接下来找出唯一一个judge的编号,以及能够确定他是的最小游戏轮数。。
数据是500,遍历每一个点, 先假设它是judge,那么其他孩子建立的制约关系,如果出现矛盾,那么这个就不是judge,judge还在其他孩子里面。。。。找最小轮数,应该是所有孩子都判定过程中出现矛盾点的最大值。。。因为每个孩子的矛盾点是能确定他不是judge的游戏轮数,则矛盾点的最大值,能判定除judge以外的所有孩子都不是judge。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 505;

int b[N];
int r[N];
typedef struct Node{
    int u,v,d;
}Node;
Node node[2005];
int n,m,ans,res;

int join(int x)
{
    int k = b[x];
    if(b[x] != x){
        b[x] = join(b[x]);
        r[x] = (r[x] + r[k]) % 3;
    }
    return b[x];
}

int solve()
{
    int cnt = 0;
    res = 0;
    ans = 0;
    for(int i = 0;i < n;++i){
        bool flag = false;
        for(int j = 0;j < n;++j){
            b[j] = j;r[j] = 0;
        }
        for(int j = 0;j < m;++j){
            if(node[j].u == i || node[j].v == i) continue;
            int tx = join(node[j].u);
            int ty = join(node[j].v);
            if(tx == ty){
                if((r[node[j].v] + node[j].d) % 3 != r[node[j].u]){
                    res = max(res,j + 1);
                    flag = true;
                    break;
                }
            }else{
                b[tx] = ty;
                r[tx] = (r[node[j].v] - r[node[j].u] + node[j].d + 3) % 3;
            }
        }
        if(!flag) cnt++,ans = i;
        if(cnt > 1) return cnt;
    }
    return cnt;
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        char s[20];
        for(int i = 0;i < m;++i){
            scanf("%s",s);
            int len = strlen(s);
            int k;
            for(int j = 0;j < len;++j){
                if(s[j] == '=' || s[j] == '<' || s[j] == '>'){
                    k = j;
                    if(s[j] == '=') node[i].d = 0;
                    else if(s[j] == '<') node[i].d = 1;
                    else node[i].d = 2;
                    break;
                }
            }
            node[i].u = 0;
            for(int j = 0;j < k;++j){
                node[i].u = node[i].u * 10 + s[j] - '0';
            }
            node[i].v = 0;
            for(int j = k + 1;j < len;++j){
                node[i].v = node[i].v * 10 + s[j] - '0';
            }
        }
        int cnt = solve();
        if(cnt > 1) printf("Can not determine\n");
        else if(cnt == 0) printf("Impossible\n");
        else printf("Player %d can be determined to be the judge after %d lines\n",ans,res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/83024522