poj 2912 Rochambeau

本文介绍了一种通过推理算法确定裁判身份的方法。使用并查集来处理人物间的关系,并通过枚举每个人作为裁判的情况来排除不可能的人选,最终找到符合条件的唯一裁判。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次想到的是枚举每个人是裁判然后判断谁是裁判的话剩下几个人的关系不矛盾,
然后满足情况的裁判个数是0矛盾,大于一多组解这点想的是对的
然后打算再跑一遍并查集然后求第二个矛盾且包含唯一裁判的条件即为答案一直wa。。。。
因为带权并查集是维护一些有特定关系的点,然而裁判和别人的关系是不固定的所以不能一起加入并查集
然后贪心 让你判断能找出裁判的最少条件 = 判断出别人不是裁判的最少条件
那就是跑n遍并查集找出其中假设每个人为裁判的下标最小的矛盾条件中的最大值
因为假设每个人为裁判当判断出这种情况不行的时候就不需要再判断了
当把所有其他人都判断出不是裁判的时候结果就出来了所以要取最大值

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 550
using namespace std;
int fa[maxn],va[maxn],n,m,ju;
char c;
int dis[505],po;
int getFa(int i)
{
    if(i==fa[i])return i;
    int pre = fa[i];
    fa[i] = getFa(fa[i]);
    va[i] = (va[i]+va[pre])%3;
    return fa[i];
}
struct node{
     int a,b;
     char c;
}no[maxn*5];
bool ok(int ju)
{
    for(int i=0;i<n;i++){fa[i] = i,va[i] = 0;}
    for(int i=0;i<m;i++)
        if(no[i].a!=ju&&no[i].b!=ju)
        {
           int flag,a=no[i].a,b = no[i].b;
           if(no[i].c=='=')flag = 0;
           else if(no[i].c=='<')flag = 1;
           else flag = 2;
           int faa = getFa(no[i].a),fab = getFa(no[i].b);
           if(faa!=fab)
           {
               fa[fab] = faa;
               va[fab] = ((3-va[b])%3+va[a]+(3-flag)%3)%3;
           }
           else if((va[a]+(3-va[b])%3)%3!=flag){po = max(po,i+1);return false;}
        }
    return true;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int sum = 0;
        ju = 0;
        po = 0;
        for(int i=0;i<m;i++)
        {
            scanf("%d",&no[i].a);
            scanf("%c",&no[i].c);
            while(no[i].c==' ') scanf("%c",&no[i].c);
            scanf("%d",&no[i].b);
        }
        for(int i=0;i<n;i++)
            if(ok(i)){sum++;ju = i;}
        if(sum>1)printf("Can not determine\n");
        else if(sum==0)printf("Impossible\n");
        else printf("Player %d can be determined to be the judge after %d lines\n",ju,po);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值