【ybt高效进阶3-1-4】【luogu P2024】食物链
发布日期:2021-05-07 06:59:53 浏览次数:22 分类:精选文章

本文共 1280 字,大约阅读时间需要 4 分钟。

食物链

题目链接: /

题目大意

有三种动物,关系是 A 吃 B,B 吃 C,C 吃 A。

然后有很多只动物,每次有一些条件,要么说两个动物是同一种,要么说一种会吃另一种。

然后问你有多少句假话。

(如果这句话跟前面的真话都不矛盾,就是真话)
(如果自己吃自己或者这个动物的变化超过了动物的数量也是假话)

思路

这道题我们先看到同类,那我们可以想到用并查集。

但是它有吃出环的关系。

那我们考虑用一个东西:扩展域并查集。

这个东西是什么呢?

它其实就是拆点之后并查集。

我们把一个动物拆成三点。

第一个点就是它自己,第二个点与吃它的点相连,第三个点就与它吃的点相连。

那我们就相同的时候就要求没有吃与被吃的关系,建立就是三个一一对应连通。

吃的时候就看会不会又相同或反吃的关系,建立就是错位连通。

听说用带权并查集也可以,但是要分来讨论很多种情况,很麻烦。

代码

#include
using namespace std;int n, k, fa[150001];int op, x, y, ans;int find(int now) { //并查集 if (fa[now] == now) return now; return fa[now] = find(fa[now]);}int main() { scanf("%d %d", &n, &k); for (int i = 1; i <= 3 * n; i++) fa[i] = i; for (int i = 1; i <= k; i++) { scanf("%d %d %d", &op, &x, &y); if ((x == y && op == 2) || x > n || y > n) { //第二第三个错误 ans++; continue; } if (op == 1) { if (find(x) == find(n + y) || find(x) == find(2 * n + y)) { //它们已经有吃与被吃的关系了 ans++; continue; } fa[find(x)] = find(y);//建立同类关系 fa[find(n + x)] = find(n + y); fa[find(2 * n + x)] = find(2 * n + y); } else { if (find(x) == find(y) || find(x) == find(2 * n + y)) { //它们已近有同类或反吃关系 ans++; continue; } fa[find(x)] = find(n + y);//建立吃关系 fa[find(n + x)] = find(2 * n + y); fa[find(2 * n + x)] = find(y); } } printf("%d", ans); return 0;}
上一篇:命令行动态弹球tanqiu.c
下一篇:二进制数的算术运算和逻辑运算

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月03日 05时12分03秒