zoukankan      html  css  js  c++  java
  • POJ

    题意:有N个人被分为了三组,其中有一个人是开了挂的。同组的人的关系是‘=’,不同组的人关系是‘<’或'>',但是开了挂的人可以给出自己和他人任意的关系。现在要根据M条关系找出这个开了挂的人。M条关系中可能有多组异常信息。可能会有多个人是外挂,也可能找不出外挂,如果能找到,则要输出其编号X和最早能确定他身份的前Y组条件。

    分析:和食物链那题性质很像,但是食物链只需要判断条件对错,而本题是要根据正确性不明的信息找出答案。

    还是用模3系的带权并查集解决该问题。枚举每个人i不是外挂的情况,对每一种情况,用不含i的关系去验证,出现矛盾则表示排除了i之外的其他中外挂,记录出现错误的关系编号。

    取N-1个人发生验证时发生错误的最大关系编号,就可以推断出谁是外挂了。

    如果每个人都不出现错误,则是不可能的情况;如果有多人可以是外挂,则不能找出;否则输出答案。

    #include<stdio.h>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int maxn =2e3+5;
    int fa[maxn],num[maxn];
    int pos[maxn];                  //错误发生的编号
    void init(int N){
        for(int i=0;i<=N;++i){
            fa[i]=i;
            num[i]=0;
        }
    }
    //模3系
    inline int Find(int x){
        if(fa[x]==x) return x;
        int f = fa[x];
        fa[x] = Find(fa[x]);
        num[x] = (num[x]+num[f])%3;
        return fa[x];
    }
    bool Union(int a,int b,int op)
    {
        int roota = Find(a),rootb =Find(b);
        if(roota==rootb){
            if((num[a]+op)%3!=num[b]) return false;
            else return true;
        }
        fa[rootb] = roota;
        num[rootb] = (-num[b]+num[a]+op+3)%3; 
        return true; 
    }
    struct Query{
        int a,b,op;
    }p[maxn];
    
    int main(){
        #ifndef ONLINE_JUDGE
             freopen("in.txt","r",stdin);
             freopen("out.txt","w",stdout);
        #endif
        int N,M,T,Q,u,v,tmp,cas=1,a,b;
        char op;
        while(scanf("%d%d",&N,&M) == 2 ){
            memset(pos,-1,sizeof(pos));
            for(int i=1;i<=M;++i){
                scanf("%d%c%d",&p[i].a,&op,&p[i].b);
                if(op=='=') p[i].op=0;
                if(op=='<') p[i].op=1;
                if(op=='>') p[i].op=2;
            }
            for(int i=0;i<N;++i){               //尝试枚举每个人不是judge的可能
                init(N);
                for(int j=1;j<=M;++j){
                    if(i==p[j].a || i==p[j].b) continue;        //跳过包含i的条件
                    if(!Union(p[j].a,p[j].b,p[j].op)) {
                        pos[i]=j;
                        break;                          //找到错误的发生即可推断出judge在i之外的人中
                    }
                }
            }
            int cnt=0,ans1=0,ans2=0;
            for(int i=0;i<N;++i){
                if(pos[i]==-1){                     //如果排除这个人不会产生问题,那么他就可以是judge
                    cnt++;
                    ans1 = i;
                }
                ans2 = max(ans2,pos[i]);            //推断n-1个人不是judge之后,也就知道了谁是judge
            }
            if(cnt>1) printf("Can not determine
    ");
            else if(cnt==0) printf("Impossible
    ");
            else printf("Player %d can be determined to be the judge after %d lines
    ",ans1,ans2);
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    Mac Pro 安装 Sublime Text 2.0.2,个性化设置,主题 和 插件 收藏
    Mac Pro 编译安装 Nginx 1.8.1
    Mac Pro 解压安装MySQL二进制分发版 mysql-5.6.30-osx10.11-x86_64.tar.gz(不是dmg的)
    Mac Pro 修改主机名
    Mac Pro 软件安装/个性化配置 汇总
    Mac Pro 安装 Homebrew 软件包管理工具
    Mac Pro 使用 ll、la、l等ls的别名命令
    Mac Pro 入门、遇到的问题、个性化设置 汇总
    Linux/UNIX线程(2)
    工作流引擎activiti入门
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9417977.html
Copyright © 2011-2022 走看看