POJ1182: 食物链(并查集运用)

POJ1182: 食物链(并查集运用)题目描述动物王国中有三类动物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句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就
摘要由CSDN通过智能技术生成

POJ1182: 食物链(并查集运用)

题目描述

动物王国中有三类动物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 sample

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

output sample

3

思路整理

(这道题困扰了我挺久,因为一直看不懂并查集,以下是按照自己的思路试着领会了一下并查集在这道题中的运用)
1.首先,这道题中,我们无法根据条件判断出每个动物具体属于A B C中的哪一类,因此我们换个思路,把题目转换为判断每句话所体现的两只动物之间的相对关系是否与到目前为止得到的信息有冲突。
2.在判断每条语句时,首先将只根据当前语句信息就能判断必然错误的语句直接判为假,具体情况有:
(1):x与y取值超过边界条件:x > N || y > N
(2):x吃y,但x与y为同一点:D=2, x == y
3.在无法通过当前语句信息判断对错时,查找之前判断为真的语句中与x和y有关的信息,在对比相关信息和当前信息,如果有冲突记为假,没有冲突就更新x与y的相关信息。

继续整理

现在我们已经把判断条件分成了2,3两步,我们主要关注第三步的实现过程。
我们假设x和y在当前语句之前已经和别的动物间产生了相对关系。
在这里插入图片描述

如上图所示,假设在这条语句前,我们已知x吃q,q=w,w被z吃。同时,我们已知t吃p,p吃z。这意味着我们间接得知了x与z的相对关系以及t与z的相对关系,因此,我们也应该能判断出x与t的相对关系,将x与t的相对关系与当前语句进行对比,即能判断当前语句是否为假。

接着我们思考另一个问题,在x与z中间还存在q与w两点,这两点在我们的实际运算中并没有起到任何作用,因此我们希望直接在x与z之间建立相对关系,而不是通过其他点来建立联系。更进一步来说,我们希望每一个确定了相对关系的集合中(在上图中,该集合为{x,q,w,z,p,t})的每一个元素能确定一个共同的祖先(根节点),使得当我们在一次碰到集合中存在的元素时,能立即通过他们与共同祖先的相对关系来判断他们之间的关系。

在这里插入图片描述
要做到这一步,我们需要压缩集合中的每个点到根节点间的距离,以上图x为例,我们不断沿着x进入它的父节点,直到最终找到根节点z,并将z的指针赋给路径中的每一个点,这样我们就实现了路径压缩,需要特别注意的是,这道题中我们我们在更改父节点的过程中,需要同时维护子节点与父节点的相对关系。

那么如果当前语句中的两个点x与y不属于同一集合(即拥有不同的根节点)时,应该怎么处理呢?
很简单,因为在当前语句之前,x与y之间还没有建立任何的相对关系,所以没有任何证据表明当前语句为假,根据题意,我们即把当前语句当做真,因此我们得到了x与y之间的相对关系。这时,我们将y的根节点的父节点置为x的根节点,我们就将包含x与y的两个不同的集合合并在一起产生了一个新的集合。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值