POJ 2912. Rochambeau

链接

http://poj.org/problem?id=2912

题意

n n n 个人进行猜拳,除了一个 judge 外,其他人只会出单一的一种,给出 m m m 种猜拳的结果,要求找出 judge 的序号,并且输出在第几次猜拳可以确定

思路

因为数据范围很小,所以可以枚举每个人是 judge 的情况,接着枚举不包含此人的猜拳结果,通过边带权并查集维护关系,因为 judge 只有一个,所以如果遇到矛盾的情况就说明在不包含此人的情况下有 judge,说明此人不是 judge,结束枚举,排除此人是 judge

枚举完成后

  • 如果排除的人大于 n − 1 n-1 n1 个,说明没有人是 judge,输出 Impossible
  • 如果排除的人小于 n − 1 n-1 n1 个,说明 judge 不止一个,输出 Can not determine
  • 如果排除的人等于 n − 1 n-1 n1 个,说明 judge 只有一个,而在枚举过程中遇到最晚的那条矛盾的结果就说明至少在此结果后能决定 judge,因为是最晚的说明排除了 n − 1 n-1 n1 个人

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<climits>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
const int N=505;
int fa[N],w[N],st[N];
struct R {
    int x,y,z;
    R() {}
    R(int x,int y,int z):x(x),y(y),z(z) {}
}r[N<<2];
int find(int x) {
    if(x==fa[x]) return x;
    int root=find(fa[x]);
    w[x]=(w[x]+w[fa[x]])%3;
    return fa[x]=root;
}
int main() {
    int n,m;
    while(~scanf("%d%d",&n,&m)) {
        for(int i=1;i<=m;i++) {
            int x,y;
            char c;
            scanf("%d%c%d",&x,&c,&y);
            if(c=='=') r[i]=R(x,y,0);
            else if(c=='<') r[i]=R(x,y,2);
            else if(c=='>') r[i]=R(x,y,1);
        }
        int cnt=0;
        PII res=MP(0,0);
        for(int i=0;i<n;i++) {
            int f=0;
            for(int j=0;j<n;j++) fa[j]=j,w[j]=0;
            for(int j=1;j<=m;j++) {
                if(r[j].x==i||r[j].y==i) continue;
                int tx=find(r[j].x),ty=find(r[j].y);
                if(tx==ty) {
                    if((w[r[j].x]-w[r[j].y]+3)%3!=r[j].z) {
                        f=j;
                        break;
                    }
                } else {
                    fa[tx]=ty;
                    w[tx]=(w[r[j].y]+r[j].z-w[r[j].x]+3)%3;
                }
            }
            if(!f) res.FI=i,cnt++;
            else res.SE=max(res.SE,f);
        }
        if(cnt==1) {
            printf("Player %d can be determined to be the judge after %d lines\n",res.FI,res.SE);
        } else if(cnt==0) {
            puts("Impossible");
        } else {
            puts("Can not determine");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值