B. 食物链【NOI2001】

内存限制:256 MiB

时间限制:1000 ms

标准输入输出

题目类型:传统

评测方式:文本比较

题目描述

动物王国中有三类动物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句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

1)当前的话与前面的某些真的话冲突,就是假话;

2)当前的话中X或Y比N大,就是假话;

3)当前的话表示X吃X,就是假话。

你的任务是根据给定的N(1≤ N ≤50,000)和K句话(0≤K≤100,000),输出假话的总数。

输入格式

第一行是两个整数N和K,以一个空格分隔。

以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。

若D=1,则表示X和Y是同类。

若D=2,则表示X吃Y。

输出格式

只有一个整数,表示假话的数目。

样例

样例输入

100 7

1 101 1

2 1 2

2 2 3

2 3 3

1 1 3

2 3 1

1 5 5

样例输出

3

数据范围与提示

100 7 1 101 1 假话 2 1 2 真话 2 2 3 真话 2 3 3 假话 1 1 3 假话 2 3 1 真话 1 5 5 真话

首先考虑题目中所说的3种矛盾情况中的后两种,都很好判断,关键是如何判断当前的话是与前面的话冲突的。

这里我们先给出两个定理以方便判断一些关系:

一.因为三个种族都有一个且且仅有一个能吃的种族。如果动物A能吃B,动物C也能吃B,那么说明 A和C便是同一个种族 ,否则这个关系就是矛盾的。

二.如果A能吃B,B能吃C,那么可以得出C能吃A,也就是如下这个关系:

对于单个点\(A_{1}\),我们可以给它建两个虚点\(A_{2},A_{3}\),并且假设出这三个点之间的关系,\(A_{1}\)吃\(A_{2}\),\(A_{2}\)吃\(A_{3}\),\(A_{3}\)吃\(A_{1}\)。同样在假设有一个点\(B_{1}\),它同样也有这些虚点。我们可以使用一个有向图来表示这个关系以方便理解。



当\(A_{1}\)可以吃掉\(B_{1}\)时,我们可以发现\(A_{1}\)和\(B_{3}\)成了同类(参考定理1,同样根据定理1,我们还可以得出\(A_{2}\)和\(B_{1}\)是同类,如果是\(B_{1}吃A_{1}则相反\))。



根据定理2,我们可以得出\(B_{1}\)可以吃掉\(A_{3}\),同时它也可以吃掉\(B_{2}\),所以\(A_{3}\)和\(B_{2}\)也是同类..



如果我们判断两个点是同类,则可以将他们放入同一个并查集中。需要注意的是,虚点只是用来帮助我们判断动物之间的关系的,并没有实际含义。

那么如何判断一句话是矛盾的呢,我们可以分情况讨论。

如果\(A_{1}\)可以吃\(B_{1}\),结合图片,我们可以发现\(A_{1}\)和\(B_{2}\),依此类推\(B_{1}\)和\(A_{3}\)也不是同类,\(A_{1}\)和\(B_{1}\)更不是同类。我们便可以使用并查集,如果上述两者在同一个并查集,便说明它们是矛盾的。

同理如果\(A_{1}\)和\(B_{1}\)是同类的话也可以这么考虑。需要注意的是,所以情况都要考虑完,实点和虚点入并查集时情况也要考虑完(不然就是WA,XD)。

可能有些同学要问为什么要判断两个点在同一个并查集,来判断这句话是不是矛盾的,而不是判断两个点不在同一个并查集,也就是

if(find(A1) == find(B2)) 矛盾

if(find(A3) != find(B2)) 矛盾

的区别。

因为我们建立的是虚点,一开始所有的点都在独立的并查集,直接判断便会误判。

可以这么理解,我们在条件不够的情况下,第二种方式是“猜测”,第一种方式则是“尽量满足关系,最后不得不判断矛盾”。

关于建立虚点,设当前有n个实点,\(A\)的两个虚点可以用\(A+n\)和\(A+2*n\)来表示.

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <map>
using namespace std; #define N 50010 int fa[N*3],n,k,ans; int find(int x) {
if(fa[x]!=x) return fa[x]=find(fa[x]);
return x;
} int main() {
cin>>n>>k;
for(int i=1;i<=n*3;i++) fa[i]=i;
for(int i=1,a,b,c;i<=k;i++) {
cin>>a>>b>>c;
if(b>n || c>n || (a==2 && b==c)) { ans++; continue; }
if(a==2) {
if(find(b)==find(c)||find(b+n*2)==find(c)||find(c+n)==find(b)) ans++;
else {
fa[find(b+n)]=find(c);
fa[find(b)]=find(c+2*n);
fa[find(c+n)]=find(b+2*n);
}
}
if(a==1) {
if((find(b+n) == find(c)) ||(find(b+2*n) == find(c))) ans++;
else {
fa[find(b+2*n)]=find(c+2*n);
fa[find(b+n)]=find(c+n);
fa[find(b)]=find(c);
}
}
}
cout<<ans;
}

C++食物链【NOI2001】 并查集+建虚点的更多相关文章

  1. 洛谷P2024 食物链 [NOI2001] 并查集

    正解:并查集 解题报告: 传送门(咕了! 其实没有很难(虽然我是交了三发才过的QAQ 但是一来好久没打并查集了恢复一下智力 二来看着智推里唯一一个蓝就很不爽(,,,虽然做了这题之后又补上了个蓝题QAQ ...

  2. 牛客网多校第4场 J Hash Function 【思维+并查集建边】

    题目链接:戳这里 学习博客:戳这里 题意: 有n个空位,给一个数x,如果x%n位数空的,就把x放上去,如果不是空的,就看(x+1)%n是不是空的. 现在给一个已经放过数的状态,求放数字的顺序.(要求字 ...

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

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

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

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

  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. P2024 [NOI2001]食物链(种类并查集)

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

  8. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  9. hdu 2473 Junk-Mail Filter(并查集_虚节点)2008 Asia Regional Hangzhou

    感觉有些难的题,刚开始就想到了设立虚节点,但是实现总是出错,因为每次设立了虚节点之后,无法将原节点和虚节点分开,导致虚节点根本无意义. 以上纯属废话,可以忽略…… 题意—— 给定n个点(0, 1, 2 ...

随机推荐

  1. STM32 总线

    AHB,是Advanced High performance Bus的缩写,译作高级高性能总线,这是一种“系统总线”.AHB主要用于高性能模块(如CPU.DMA和DSP等)之间的连接.AHB 系统由主 ...

  2. 服务器上搭建jupyter notebook

    参考:https://zhuanlan.zhihu.com/p/44405596 https://blog.csdn.net/cvMat/article/details/79351420 遇到的问题 ...

  3. Codeforces 957 水位标记思维题

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  4. RMQ 区间最大值最小值 最频繁次数

    区间的最大值和最小值 #include <cstdio> #include <cstring> #include <cmath> #include <iost ...

  5. python碎片化 - 集合set

    集合set:无序,不重复的数据类型 list1={1,2,3,4,5} list2={6,5,4,7,8,9,} list3={1,2,3} s = set([3,5,9,10]) #交集 print ...

  6. synchronized和lock的使用分析(优缺点对比详解)

    1.synchronized加同步格式: synchronized(需要一个任意的对象(锁)){ 代码块中放操作共享数据的代码. } synchromized缺陷synchronized是java中的 ...

  7. Apache+Mysql+PHP 套件

    Apache+Mysql+PHP 套件   最近要装个Apache+Mysql+PHP的一个环境. google下后,发现现在的安装变得越来越简单了.不再需要麻烦的配置安装,只需简单执行个sh就搞定了 ...

  8. 【leetcode】1109. Corporate Flight Bookings

    题目如下: There are n flights, and they are labeled from 1 to n. We have a list of flight bookings.  The ...

  9. php end()函数 语法

    php end()函数 语法 作用:将数组内部指针指向最后一个元素,并返回该元素的值(如果成功).博智达 语法:end(array) 参数: 参数 描述 array 必需.规定要使用的数组. 说明:如 ...

  10. luogu P1068 分数线划定 x

    P1068 分数线划定 题目描述 世博会志愿者的选拔工作正在 A 市如火如荼的进行.为了选拔最合适的人才,A 市对 所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试.面试分数线根 据 ...