poj 1182 并查集

题意:三种动物,A吃B, B吃C,C吃A。 现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。 

有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是"1 X Y",表示X和Y是同类。
第二种说法是"2 X Y",表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
输出假话的总数。

分析:

1.p[x]表示x的根结点。r[x]表示p[x]与x的关系。r[x] == 0 表示p[x]与x同类;1表示p[x]吃x;2表示x吃p[x]。

2.集合不是根据x与p[x]是否是同类来划分,而是根据能否确定x与p[x]的关系来划分。

3.若 D == 1 而 r[X] != r[Y] 则此话为假。
   若 D == 2 而 r[X] == r[Y] 或者 r[X] == ( r[Y] + 1 ) % 3 (Y吃X )则此话为假。

假设Y吃X: r[X] = 0 && r[Y] = 2
              r[X] = 1 && r[Y] = 0
              r[X] = 2 && r[Y] = 1
可知 r[X] = ( r[Y] + 1 ) % 3;

4.在union_set( rx , ry )过程中若将S(ry)合并到S(rx)上,则相应的r[ry]必须更新为ry相对于rx的关系。已知关系: rx与x, ry与y, x与y,易得rx与ry的关系。

 

 

const int MAXSIZE = 50005;
int rank[MAXSIZE];   // 节点高度的上界
int parent[MAXSIZE]; // 根节点
int r[MAXSIZE];
int FindSet(int x){// 查找+递归的路径压缩
    int px=parent[x];
    if(x!=parent[x]) parent[x]=FindSet(parent[x]);
    r[x]=(r[px]+r[x])%3;//r[x]存放的是x对于根的偏移量   这里的 根 只能是px
    return parent[x];
}
void UnionSet(int x,int y,int rx,int ry,int d){
     if(rx==ry) return;
     /*parent[ry] = rx;
      r[ry] = ( r[x] - r[y] + 2 + d ) % 3;*/
     if(rank[rx]>rank[ry]){
         parent[ry]=rx;
         r[ry]=(r[x]-r[y]+2+d)%3;
     }
     else{
         parent[rx]=ry;
         r[rx]=(r[y]-r[x]-d+4)%3;
         if(rank[rx]==rank[ry])rank[ry]++;
     }
}
void MakeSet(int SIZE){
     for(int i=0;i<=SIZE;i++) {
         parent[i]=i; r[i]=rank[i]=0;
     }
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    MakeSet(n);
    int d,x,y,cnt=0;
    int rx,ry;
    while(k--){
        scanf("%d%d%d",&d,&x,&y);
        rx=FindSet(x); ry=FindSet(y);
        if(d==1){
            if(x>n||y>n)cnt++;
            else if(rx==ry&&r[x]!=r[y])cnt++;
            else UnionSet(x,y,rx,ry,d);
        }
        else{
            if(x>n||y>n||x==y)cnt++;
            else if(rx==ry&&r[x]!=(r[y]+2)%3)cnt++;
            else UnionSet(x,y,rx,ry,d);
        }
    }
    cout<<cnt<<endl;
    return 0;
}

 

posted @ 2013-06-22 14:19  心向往之  阅读(129)  评论(0编辑  收藏  举报