POJ 1182 食物链 (拆点并查集)

食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 78601   Accepted: 23422

Description

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。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,就是假话。 
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 

Input

第一行是两个整数N和K,以一个空格分隔。 
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 
若D=1,则表示X和Y是同类。 
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

Sample Output:

思路:
拆点并查集,字面意思将一个点拆成数个点来进行并查集操作,比如a点拆成三个点变成a-x,a-y,a-z.分别代表属于不同的类,如果b和a是同一种族,那么就可以分别将a-x与b-x,a-y与b-y,a-z与b-z用并查集连接在一起,那么如果发现a-x和b-y,b-z相连那么肯定就和前面矛盾了,他们属于不同的类。没有关系不能连在一起。如果是捕食关系的话,因为该食物链组成了一个环,那么可以变成,x吃y,y吃z,z吃x。那么a,b之间的关系就有:a-x吃b-y,a-y吃b-z,a-z吃b-x.如果又不属于这个关系链的出现那么就矛盾了,假话+1.

这个解释起来太麻烦了。。心态爆炸,实在说不来。。结合代码的话应该会好一些

 

实现代码:

#include<iostream>
#include<cstdio>
using namespace std;
int pre[50009*3];
void init(int n){
    for(int i=0;i<=n;i++){
        pre[i] = i;
    }
}

int find(int x){
    if(x==pre[x])
        return x;
    int temp = pre[x];
    pre[x] = find(temp);
    return pre[x];
}

int same(int x,int y){
    int fx = find(x);int fy = find(y);
    if(fx == fy) return 1;
    else return 0;
}

void mix(int x,int y){
    int fx = find(x);int fy = find(y);
    pre[fx] = fy;
}

int main()
{
    int n,m,ans,x,y,d;
    ans = 0;
   scanf("%d%d",&n,&m);
   init(3*n);
   while(m--){
      scanf("%d%d%d",&d,&x,&y);
      if(x<1||x>n||y<1||y>n){
        ans++;continue;
      }
      if(d==1){
          if(same(x,y+n)||same(x,y+n*2))
            ans++;
          else{
            mix(x,y);mix(x+n,y+n);mix(x+n*2,y+n*2);
          }
      }
      else{
        if(same(x,y)||same(x,y+2*n))  ans++;
        else{
            mix(x,y+n);mix(x+n,y+2*n);mix(x+2*n,y);
        }
      }
   }
   printf("%d",ans);
   return 0;
}

 


posted @ 2017-11-09 16:53  冥想选手  阅读(185)  评论(0编辑  收藏  举报