题目链接:1182-食物链 代码如下:

       首先这道题要弄明白的是题目中的“当前的话与前面的某些真的话冲突,就是假话”到底是什么意思。事实上,第一句话肯定是真的,因为假如第一句话是假的,那我们就没有可以判断第二句话真假的依据了。接下来要做的其实只是判断当前的话与上面的话是否冲突。要注意的是,如果当前描述下,x与pre[x]无确定的关系,即fx!=fy,则将当前说法看作是正确的来进行merge。如果有确定的关系,再根据(rankr[x]-rankr[y]+3)%3与d-1的关系来判断对错。如果两者不相等,则为错;否则,对。 那么,如何进行集合的划分呢?在这道题里,集合的划分依据不是是否为同类,而是“是否能确定两者之间的关系”。(“ 注意,这里不是根据x与father[x]是否是同类来划分。而是根据“x与father[x]能否确定两者之间的关系”来划分,若能确定x与father[x]的关系,则它们同属一个集合”,摘自题解)        在判断的时候,如果输入的两只动物不是附属于同一个根节点,及不能确定两者的关系,就进行merge,merge的时候还要更新被并入的那个集合(即新的子树)的根节点的权值(即他与新的根节点的关系)。再合并的时候,我们只需要进行根节点的权值更新,被并入的集合的子节点的权值通过findr()顺带更新(这也是带权并查集的精髓和难点)        在这道题中,并查集并不是要体现层级关系。同一棵树中的各个节点之间其实只是平等的几何元素关系,而没有上下级关系(或者说上下级关系对这道题而言没用)