zoukankan      html  css  js  c++  java
  • [poj 2912] Rochambeau 解题报告 (带权并查集)

    题目链接:http://poj.org/problem?id=2912

    题目:

    题目大意:

    n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000)

    接下来m行形如x,y,ch的输入,ch='='表示x,y平局, ch='>'表示x赢y,ch='<'表示x输y, 但是我们不知道x,y的手势是什么;

    其中有一个人是裁判,它可以出任意手势,其余人手势相同的分一组,共分为三组,可以存 在空组。

    也就是说除了裁判外,其余人每一次出的手 势都相同,问能不能确定裁判是几号,如果能,输出 最少在第几轮可以确定;

    题解:

    带权并查集

    我们考虑枚举裁判,然后对每轮进行处理,包含当前枚举的裁判的轮我们直接跳过

    二者之前的关系我们用0(=),1(>),2(<)表示,记得%3,用val数组记录当前点到所在并查集根节点的关系

    对于每轮,我们首先判断是否在同一联通块里。如果在,判断当前关系是否符合,即val[b]是否等于val[a]+ch(我们定义ch是b连向a的),如果是就继续,不是的话说明当前的点不是裁判;如果不在,就带权合并一下就好了

    那么最少的发现裁判的轮数呢?我们发现我们实际上在做一个排除法,那么我们最晚排除的那个人的轮数就是最少的发现裁判的轮数

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N=500+15;
    const int M=2000+15; 
    int n,m;
    int fa[N],a[M],b[M],ch[M],val[N];
    int find(int x)
    {
        if (fa[x]==-1) return x;
        int tmp=find(fa[x]);
        val[x]+=val[fa[x]];
        val[x]%=3;
        return fa[x]=tmp;
    }
    int main()
    {
        while (~scanf("%d%d",&n,&m))
        {
            char c[10];
            for (int i=1;i<=m;i++)    
            {
                scanf("%s",c+1);
                a[i]=b[i]=0;
                int len=strlen(c+1);
                int l=1;
                while (c[l]>='0'&&c[l]<='9') a[i]=(a[i]<<3)+(a[i]<<1)+c[l]-'0',l++;
                if (c[l]=='=') ch[i]=0;
                if (c[l]=='>') ch[i]=1;
                if (c[l]=='<') ch[i]=2;
                l++;
                while (c[l]>='0'&&c[l]<='9'&&l<=len) b[i]=(b[i]<<3)+(b[i]<<1)+c[l]-'0',l++;
                //printf("%d %d %d
    ",a[i],ch[i],b[i]);
            }
            int round=0,judger=-1;
            bool mark=false;
            for (int i=0;i<n;i++)
            {
                bool flag=false;
                memset(fa,-1,sizeof(fa));
                memset(val,0,sizeof(val));
                for (int j=1;j<=m;j++)
                {
                    if (a[j]==i||b[j]==i) continue;
                    int fx=find(a[j]),fy=find(b[j]);
                    if (fx==fy)
                    {
                        if (val[b[j]]!=(val[a[j]]+ch[j]+3)%3)
                        {
                            round=max(round,j);
                            flag=true;
                            break;
                        }
                    }
                    else 
                    {
                        fa[fy]=fx;
                        val[fy]=(val[a[j]]+ch[j]-val[b[j]]+3)%3;
                    }
                }
                if (!flag)//当前的是法官 
                {
                    if (judger==-1)
                    {
                        judger=i;
                    }
                    else 
                    {
                        mark=true;
                        break;
                    }
                }
            }
            if (mark) printf("Can not determine
    ");
            else if (judger==-1) printf("Impossible
    ");
            else printf("Player %d can be determined to be the judge after %d lines
    ",judger,round);
        }
        return 0;
    }
  • 相关阅读:
    spring多数据源配置
    spring+myBatis 配置多数据源,切换数据源
    Maven项目引入log4j的详细配置
    基于Https协议返回Jason字符串
    Http协议入门、响应与请求行、HttpServletRequest对象的使用、请求参数获取和编码问题
    java http post/get 服务端和客户端实现json传输
    java实现一个简单的Web服务器
    设计模式系列
    Nginx系列
    Linux系列
  • 原文地址:https://www.cnblogs.com/xxzh/p/9668933.html
Copyright © 2011-2022 走看看