码迷,mamicode.com
首页 > 其他好文 > 详细

Rochambeau ——带权并查集

时间:2019-10-01 12:15:26      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:else   并且   ini   print   main   石头剪刀布   pre   splay   https   

题目链接

题意:

石头剪刀布,有一个人时裁判,给你一系列情况,让你判断裁判的情况:

有一个裁判-------player x can be determined to be the judge after y lines

没有裁判,谁是裁判都不成立-------Impossible

有多个裁判-------Can not determine

“裁判”的意思是,比如0是裁判,则去掉含有0的行,剩下的行成立。

 

题解:

做法类似食物链题目

u=v  记为 0

u<v  记为 1

u>v  记为 2

因为数据范围不大,所以枚举每一个人是否为裁判,对于枚举的人,不进行并查集操作,看剩下的游戏中是否会有矛盾

如果有矛盾,则说明这个人不是裁判,并且记录那个回合出现矛盾,否则他就可能是裁判

 

然后就遍历所有人看是否只有一个人没有出现矛盾,如果只有一个,则说明可以确定裁判,那么确定裁判的局数就是其他人出现矛盾的回合的最大值。因为只有否定了其他所有人,才能够确定才裁判。

 

代码:

技术图片
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int d[maxn];
int f[maxn];
int ans[maxn];
int n,m;
struct node
{
    int u,v;
    int r;
} a[maxn];
int Find(int x)
{
    if(x==f[x])return x;
    int root=Find(f[x]);
    d[x]=(d[x]+d[f[x]])%3;
    return f[x]=root;
}
void init()
{
    for(int i=0; i<=n; i++)f[i]=i,d[i]=0;
}
int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=m;i++)
        {
            char op;
            scanf("%d%c%d",&a[i].u,&op,&a[i].v);
            if(op===)a[i].r=0;
            else if(op==<)a[i].r=1;
            else a[i].r=2;
        }
        memset(ans,-1,sizeof ans);
        for(int i=0;i<n;i++)
        {
            init();
            for(int j=1;j<=m;j++)
            {
                if(i==a[j].u || i==a[j].v)continue;
                int fx=Find(a[j].u);
                int fy=Find(a[j].v);

                if(fx==fy)
                {
                    if((d[a[j].v]-d[a[j].u]+3)%3 != a[j].r)
                    {
                        ans[i]=j;
                        break;
                    }
                }
                else
                {
                    f[fx]=fy;
                    d[fx]=((d[a[j].v]-a[j].r-d[a[j].u]+3)%3+3)%3;
                }
            }
        }
        int cnt=0;
        int res1=0,res2=0;
        for(int i=0;i<n;i++)
        {
            if(ans[i]==-1)
            {
                cnt++;
                res1=i;
            }
            res2=max(res2,ans[i]);
        }
        if(cnt==0) 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", res1, res2);

    }

    return 0;
}
View Code

 

Rochambeau ——带权并查集

标签:else   并且   ini   print   main   石头剪刀布   pre   splay   https   

原文地址:https://www.cnblogs.com/j666/p/11614974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!