题意

P1024

简化题意:给定 \(n\) 和 \(k(n\leqslant5\times10^4,k\leqslant10^5)\) ,表示有 \(n\) 个动物, \(k\) 个描述,其中:

\(n\) 个动物分别属于 \(A,B,C\) 中的一种,定义如 \(C\to B\to A\to C\) 的环形食物链;

\(k\) 个描述分两种:1.1 x y表示 \(x,y\) 是同类; 2. 2 x y表示 \(y\to x\) .

在 \(k\) 个描述中,有真假之分,其中假的满足:

  • 与之前的真话矛盾;
  • \(x\) 或 \(y\) 比 \(n\) 大;
  • 同类相吃。

求出假话总数。

思路

思路启发

首先进来一组 \(x,y\) ,易得有且仅有三种有用的关系:

  • \(y\) 是 \(x\) 的同类。
  • \(y\to x\) , \(y\) 是 \(x\) 的猎物;
  • \(y\to x\) , \(x\) 是 \(y\) 的天敌。(其实是与关系1是相互的)

那么,我们要维护三个逻辑关系,即有联通性,又有对立性,就要开 三元种类并查集 了。

实际上就是把一个并查集扩大三倍,在每个并查集里维护联通性,即同类关系;在三个并查集之间维护对立性,即猎物和天敌关系。

实际利用

我们可以假设:(\(B\to A\to C\to B\) ,满足题干关系就行)

  • 集合\(A(1\sim n)\) 为中间者;
  • 集合\(B(n+1\sim 2n)\) 为猎物;
  • 集合\(C(2n+1\sim 3n)\) 为天敌;

现在的目的就是用三个集合,依次维护正确的逻辑关系,如果有假话,那么应无法在上面成立,统计无法成立的关系即可。

不妨用图模拟个样例:

点击查看样例
4 5
1 1 3
2 2 4
2 3 2
1 1 4
2 2 1

\(k_1:\) \(1\) 和 \(3\) 是同类,那么就把它俩合并到一个集合,同时注意到,都在集合\(A\) 中,则分别都会在集合\(B\) 和集合\(C\) 中,它俩同类,那它俩的猎物和天敌必定同类。

\(k_2:\) \(2\) 吃 \(4\) ,则有两个逻辑关系:

  • \(4\) 是 \(2\) 的猎物,此时 \(2\) 是中间者,在集合\(A\) ,\(4\) 是猎物,在集合\(B\) ,即 \(4(B)\to2(A)\) ;
  • \(2\) 是 \(4\) 的天敌,此时 \(4\) 是中间者,在集合\(A\) ,\(2\) 是天敌,在集合\(C\) ,即 \(4(A)\to2(C)\) ;

但我们观察 \(B\to^1 A\to^2 C\to^3 B\) ,关系 \(3\) 也应存在才能形成循环,即 \(4(C)\to2(B)\) ;

\(k_3:\) 同理。

\(k_4:\) 此时 \(1\) 与 \(4\) 是同类的是假的。

判断同类是否为假,即判断是否存在 \(1\to4\) 或 \(4\to1\) 的情况,即 \(4\) 的猎物是否是 \(1\) 或 \(4\) 的天敌是否是 \(1\) 。(判断有多样,这样统一了左边的 \(1\))

我们非别求一下对应点的根节点看看:

\(k_5:\) 此时 \(2\) 吃 \(1\) 是假的。

判断吃与被吃是否为假,即判断是否存在 \(2\) 与 \(1\) 是同类或 \(2\to1\) 的情况,即 \(2\) 和 \(1\) 是否在同一集合(此时三个集合显然是等效的)或 \(1\) 的猎物是否是 \(2\) 。

code

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10,K=1e5+10;
int n,k,fa[3*N],cnt;
int get(int x)
{
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y)
{
fa[get(x)]=get(y);
}
int main()
{
cin>>n>>k;
for(int i=1;i<=3*n;i++) fa[i]=i;
for(int i=1;i<=k;i++)
{
int op,x,y;
cin>>op>>x>>y;
if(x>n || y>n) { cnt++; continue; }
if(op==1)
{
if(get(x)==get(y+n) || get(x)==get(y+2*n)) cnt++;
else
{
merge(x,y);
merge(x+n,y+n);
merge(x+2*n,y+2*n);
}
}
else
{
if(get(x)==get(y) || get(x)==get(y+n)) cnt++;
else
{
merge(x,y+2*n);
merge(x+n,y);
merge(x+2*n,y+n);
}
}
}
cout<<cnt<<endl;
return 0;
}

总结

种类并查集不仅可以维护联通性,也可以维护对立性。

P1024 [NOI2001] 食物链【种类并查集】的更多相关文章

  1. P2024 [NOI2001]食物链(种类并查集)

    题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...

  2. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...

  3. POJ1182 食物链 —— 种类并查集

    题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

  4. 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集

    P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...

  5. [NOI2001] 食物链 (扩展域并查集)

    题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...

  6. [NOI2001]食物链(并查集拓展域)&& [HAOI2006]旅行(Kruskal)

    题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...

  7. POJ 1182 食物链(种类并查集)

    记得第一次做这道题的时候,推关系感觉有点复杂,而且写完代码后一直WA,始终找不出错误. 在A了十几道并查集后,再做这道题,发现太小儿科了.发现原来之所以WA,就在于查找根节点时,没有同步更新子节点相对 ...

  8. 洛谷 P2024 [NOI2001]食物链 (并查集)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P2024 这道题和团伙这道题的思想比较类似,都是一个数组分成几个集合,但这道题的思路更加混乱,建议没做 ...

  9. P2024 [NOI2001]食物链[扩展域并查集]

    大水题一道啊,几分钟切掉. 还是扩展域,每个点拆3个点,之间连边表示有关系(即捕食关系).然后随便判定一下就好了,不难,毕竟NOI上古题目. #include<iostream> #inc ...

  10. 洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)

    传送门 解题思路 加权并查集: 什么是加权并查集? 就是记录着每个节点到它的父亲的信息(权值等). 难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值 怎么转化呢? 每道题都不一样Q ...

随机推荐

  1. css 悬停图片改变图片的样式

    <style> #div{ text-align: center; } .img{ width: 200px; clip-path: polygon(50% 0,100% 50%,50% ...

  2. Linux-->开关机+用户管理指令

    关机与重启指令 shutdown关机 语法: shutdown -h 关机时间 now 立刻 1 1分种后 shutdown重启 语法: shutdown -r 重启时间 now 立刻 1 1分钟后 ...

  3. 使用MVC的实现登录注册功能

    文章目录 1.视图层(View)页面的编写: 1.1.登录页面 1.2.注册页面 2.控制层(Controller)的编写 2.1. 注册 2.2 .登录 2.3 .实体类 3.Model层(Mode ...

  4. 齐博x1标签实例:标签的嵌套用法,调用聚合数据

    齐博标签非常强大,可以让不懂程序的你,轻松就能实现所见即所得. 下面跟大家讲解一下,最复杂的运用, 同时使用了union 动态变量参数 与 分页处理标签 比如下面这张图,不仅仅想调用圈子,还想同时调用 ...

  5. 齐博x1小程序集群一个重要功能升级,可以根据圈子会员组显示不同的菜单。

    如下图所示,虽然之前圈子小程序可以自定义会员中心菜单,但是存在一个问题,就是所有会员,比如圈主与普通会员的菜单都将是一样的. 现在升级后,就可以设置不同的圈子会员组,拥有不同的菜单. 比如一个商家,店 ...

  6. DQL-聚合函数

    DQL-聚合函数 SQL基本函数,聚合函数对一组值执行计算,并返回单个值,也被称为组函数. 聚合函数对一组值执行计算并返回单一的值.除 COUNT 以外,聚合函数忽略空值,如果COUNT函数的应用对象 ...

  7. ES6 学习笔记(九)Set的基本用法

    1 基本用法 set类似于数组,它的成员是唯一的,当有多个相同的值,只会保留一份. 1.1 创建方法 Set本身是一个构造函数,用来生成Set实例,如: const s = new Set() let ...

  8. day02-实现01

    实现01 1.实现任务阶段1 编写mytomcat,该服务器能给浏览器返回"你好,我是服务器!"的简单信息. 根据之前的tomcat框架整体分析,我们将浏览器发送请求,tomcat ...

  9. ThinkPhp5 自定义异常处理类

    在项目的开发过程中异常抛出尤为重要不仅能够做出友好提示帮助掩盖我们伟大的程序员们尴尬的瞬间,还能做到提示开发人员代码白编写的错误,下面进行自定义异常抛出类,纯属个人理解,希望大家指正 首先在框架中我们 ...

  10. 【经验分享】配置用户通过Console口登录设备示例

    组网需求 当用户无法进行远程登录设备时,可通过Console口进行本地登录.缺省情况下,使用Console用户界面登录设备时只需要密码认证.为了防止非法用户登录设备,修改Console用户界面的认证方 ...