POJ 1182 食物链 并查集

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66964#problem/E

题意:求假话的数量。

怎么说呢?题目就是会了不难,难的不会!!在网上了看了N多题解,绝大多数都是用一个什么公式来更新的,感觉那个真的不太适合我,说以也就没管了。偶然在白神的一本上看到了此题的另一种解法,可以说是通俗易懂,nice!上正文:

思路:维护每一个动物的三种关系:自己同类的,吃自己的,被自己吃的。如果用三个数组来来维护,即:A表示同类,B表示被自己吃的,C表示吃自己的,那么这样一来,就不能用同一个pre数组来维护了,因为A[i],B[i],C[i]这三个集合的意义是不一样的,但是pre[i] 却只有一种意思。怎么办呢?其实很简单,为了解决pre的重复问题,我们开一个三倍于N一维数组就行了。其中1~N表示同类,N+1~N+N表示1~N对应的动物所吃,2N+1~2N+N表示吃1~N对应的动物,这样一来,我们就可以用一个pre数组来维护三者之间的关系了。

此题还得注意的是:只有一组数据输入,否则会WA。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;

int pre[maxn*3];
int N,K;

int find(int x){
    int t=x;
    while(pre[t]!=t) t=pre[t];
    while(x!=t) pre[x]=t,x=pre[x];
    return t;
}

int judge(int a,int b,int c){
    if(a==2 && b==c) {return 0;}
    if(b>N || c>N) {return 0;}
    int fb=find(b),fc=find(c);
    if(a==1){
        if(fb==find(c+N) || fb==find(c+2*N)){ return 0;}
        pre[fb]=fc;
        pre[find(b+N)]=find(c+N);
        pre[find(b+2*N)]=find(c+2*N);
        return 1;
    }
    if(fb==fc || fb==find(c+N)) {return 0;}
    pre[fb]=find(c+2*N);
    pre[find(b+N)]=fc;
    pre[find(b+2*N)]=find(c+N);
    return 1;
}

int main(){
    //freopen("D:in.txt","r",stdin);
    cin>>N>>K;
    int a,b,c,ans=0;
    for(int i=0;i<=3*N;i++) pre[i]=i;
    for(int i=0;i<K;i++){
        scanf("%d %d %d",&a,&b,&c);
        if(judge(a,b,c)) continue;
        ans++;
    }
    cout<<ans<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值