poj 1182 食物链

题目链接:点击打开链接


并查集经典题

本题的解法比较难像,因为不知道每个动物属于哪个种类,所以给他假设3种状态,这三种状态可能分别是A,B,C   B,C,A;  C,A,B;

这样维护三个并查集,每次读入信息对这三种状态检测是否有误,无误就更新,具体看代码实现吧。


坑:本题单组数据,如果写成多组数据输入会WA!

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int fa[50010*3];
int Find(int n){
    if(n==fa[n]) return n;
    return fa[n]=Find(fa[n]);
}

bool same(int m,int n){
    return Find(m)==Find(n);
}

void Union(int n,int m){
    int p1=Find(n);
    int p2=Find(m);
    if(p1!=p2) fa[p1]=p2;
}

void init(int n){
    for(int i=1;i<=3*n+3;i++){
        fa[i]=i;
    }
}

int main(){
    int n,K;
    scanf("%d%d",&n,&K);
          init(n);
          int res=0;
          for(int i=1;i<=K;i++){
              int a,b,c;
              scanf("%d%d%d",&a,&b,&c);
              if(b<1||b>n||c>n||c<1){ res++; continue;}
              if(a==1){
                  if(same(b,c+n)||same(b,c+2*n)) res++;
                  else{
                    Union(b,c);
                    Union(b+n,c+n);
                    Union(b+2*n,c+2*n);
                  }
              }
              else{
                  if(same(b,c)||same(b,c+2*n)) res++;
                  else{
                    Union(b,c+n);
                    Union(b+n,c+2*n);
                    Union(b+2*n,c);
                  }
              }
          }
          printf("%d\n",res);
    return 0;
}



你可能感兴趣的:(并查集)