1182 食物链(POJ)

8 篇文章 0 订阅

题意理解

有N个动物,分为三类,A、B和C类,A吃B,B吃C,C吃A,现有K句话,每句话说明两个动物的关系,

1 X Y说明X和Y是同类

2 X Y说明X吃Y

K句话有真有假,假话的判断标准是三个:

1 当前话和之前话冲突

2 X,Y超过100

3 X吃X

求有多少假话?

问题分析

用并查集

每句话确定两个动物之间的关系,2,3两句假话直接判断即可,第1句假话比较难。

不管同类还是被吃的关系,都有可能是三种实质种类,对于同类来讲,有AA,BB,CC;对于被吃关系来讲,有AB,BC,CA;

结合并查集的特点,关联元素放在一个集合再指向祖先节点,这里有两种关系,如何表示关联?

转一:初始集合扩充2倍,分别表示A类,B类,C类,每类有N个元素,这样同类关系存在三组元素,每组两个元素的关联;被吃关系存在三组元素,每组也是两个元素的关联。就可以穷尽各种关系的表示。这两种关联的表示是不同的,同类关联是指向了同类中共有的祖先节点;被吃关联是改变同类中祖先的节点指向了非同类的另一个类中的某个祖先。换句话说,只有祖先的节点才会指向非同类的节点,这种指向指示被吃关系。

接下来要判断假话的标准是什么,对于一个关系,如何判断是不是与已知的并查集冲突?

设两个元素X,Y表明是同类关系,如果X的祖先和Y+N的祖先相同,或X的祖先和Y+2N的祖先相同,说明他们不是同类,因为X和Y+N分属不同的类别,X和Y+2N分属不同的类别。

设两个元素X,Y表明是被吃关系,如果X的祖先和Y的祖先相同,或X的祖先和Y+2N的祖先相同,说明他们不是被吃关系,因为X和Y属于同类别,X和Y+2N属于反被吃关系。

 

其他

运用巧妙,知道并查集也不知道如何用

并查集的扩展,尤其在两个关系的处理上思路还转不过来

我想到了将这种关系固定化,固定化到具体的三个祖先节点,但是丧失了灵活性,这种扩展集合的方式不仅充分保留了关系的关联,而且将同类关系和被吃关系准确的表达出来,通过同一祖先的表示,判断两者关系是不是冲突。绝了。

我的思路用循环链表表示同类的三种情况,用了无数的if判断,但漏了被吃关系的三种表示,我片面的想成了一种。导致我花了半天在排查错误,这个过程让我想到了,我思维的推理缺陷导致了无用功。凡事先推理合理再进行下笔,不要偷思维的懒。

具体的东西好上手但没有准确的思维垫底,很容易白费劲。这是科学不是纸上谈兵。

运用知识的能力是我的短板,掌握再多的知识,不能用起来是么有用的,我需要多思考思路,而不是铺开学太多的东西。

我在做的东西对我的帮助是巨大的,看博士的预答辩内容一层一层展开,清晰明了,说明思维的刻苦训练有效果的。“妄自菲薄”不应是我的主旋律。

代码链接

https://github.com/xierensong/learngit/blob/master/poj/p1182.cpp

参考:https://blog.csdn.net/backforward/article/details/51892505

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值