poj 2912(并查集,食物链)

本文介绍了一种使用并查集数据结构来解决食物链关系判断问题的方法。通过定义特殊的关系运算,能够有效地更新和查询两个元素之间的关系,如大于、小于或等于。文章提供了一个完整的C++实现示例,可用于解决类似问题。


因为和食物链题一样的性质,所以处理和食物链那题一样。

性质: 如果 A>B  并且 B>C 时,  则 A<C ;

所以用并查集关系式处理如下 

A>B   处理成      F【A】=B,SUM【A】=2;

A<B   处理成      F【A】=B,SUM【A】=1;

A==B 处理成      F【A】=B,   SUM【A】=0;

例如  A>B,  B>C,看此时变化。

先处理 A>B ,F【A】=B,SUM【A】=2;

再处理 B>C,F【B】=C,SUM【B】=2,;  F【A】=C,SUM【A】=(SUM【A】+SUM【B】)%3= 1 ;

问此时 A和B 的关系,就等于 k=(SUM【A】- SUM【B】+3)%3 ; K值此时就对应上边的关系式。 


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define mem(p,k) memset(p,k,sizeof(p));
#define rep(i,j,k) for(int i=j; i<k; i++)
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x6fffffff
#define ll long long
using namespace std;
const int mod=1e9+7;
char s[2100];
int bk[220],f[50000],sum[5100];
int n,m,k,minn,maxx,ans,cur,x[2100],y[2100];
int nex[4][2]={0,1,1,0,0,-1,-1,0};
int nextt[101000];
int fin(int x){
    if(x==f[x])return x;
    int ff=fin(f[x]);
    sum[x]=(sum[x]+sum[f[x]])%3;
    return f[x]=ff;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){
    rep(i,0,m){
       scanf("%d%c%d",x+i,s+i,y+i);
      // if(x[i]>=n||x[i]<0||y[i]>=n||y[i]<0)cur=1;
    }
    maxx=0,ansnum,sum1=0;
    rep(i,0,n){
       mem(sum,0);
       rep(j,0,n)f[j]=j;
       int cur1=0;
       rep(j,0,m){
          if(x[j]==i||y[j]==i){
            continue;
          }
          k=0;
          if(s[j]=='>')k=2;
          else if(s[j]=='<')k=1;
          int xx=fin(x[j]),yy=fin(y[j]);
          if(xx==yy){

              if(((sum[x[j]]-sum[y[j]]+3)%3)!=k){
                  cur1++;
                  maxx=max(maxx,j+1);break;
              }
          }
          else{
             f[xx]=yy;
             sum[xx]=(k+sum[y[j]]-sum[x[j]]+3)%3;
          }

       }
       if(!cur1){
            sum1++;ansnum=i;
       }
       if(sum1>1)break;
    }
    //cout<<sum1<<endl;
    if(sum1==0){
        cout<<"Impossible"<<endl;
    }
    else if(sum1==1){
        printf("Player %d can be determined to be the judge after %d lines\n",ansnum,maxx);
    }
    else cout<<"Can not determine"<<endl;
    }
    return 0;
}
//freopen("C:\\Users\\LENOVO\\Desktop\\read.txt","r",stdin);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值