题目:
动物王国中有三类动物 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 句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。当前的话与前面的某些真的话冲突,就是假话;当前的话中 X 或 Y 比 N 大,就是假话;当前的话表示 X 吃 X,就是假话。你的任务是根据给定的 N和 K 句话,输出假话的总数。
思路:
1.整体思路:
当给出语句阐述x,y的关系时,查找x,y的关系,若x,y之间有关系且与语句相悖,则假话数量增加;若x,y之间没有关系,则构建x,y之间的关系。
2.具体思路:
问:如何查询x,y之间的关系?
答:
首先判断x,y之间是否有关系。x,y之间可能有直接的关系(比如:前面出现语句x吃y),也可能有间接的关系。(比如:前面出现语句x吃a,a吃y,由此得到y吃x)所以,不妨将构成一条食物链的所有点放进一个连通分支里。
进一步判断,若x,y在一条连通分支上,x,y之间是什么样的关系呢?可以看到,x,y只可能有三种关系——吃、被吃、同类。既然如此,不如给任意点都设立一个位置下标作为到相邻结点的距离,由此可以表示该点与相邻结点之间的关系。
规则如是。设d[x]为a,a%3=1,则x吃相邻结点;a%3=2,则x被相邻结点吃;a%3=0,则x与相邻结点同类。(模三的原因是为了对应x与相邻结点的关系恰好有三种可能)
问:如何构造x,y的关系?
答:
我们维护上述规则即可。(规则:设d[x]为a,a%3=1,则x吃相邻结点;a%3=2,则x被相邻结点吃;a%3=0,则x与相邻结点同类。)
打个比方,如果我们要构造x吃y的关系,只需要将x所在的连通分支与y的连通分支合并(放进一条食物链)。
具体操作:将x的邻接顶点更新为x的源头r1,y的邻接顶点更新为y的源头r2,再将x的源头连接y的源头。由x吃y得到,x到y的距离为三的倍数加一,而此时d[x]=d[r1]+d[y],所以我们将d[r1]更新为d[x]-d[y]。
代码展示: