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. DOMContentLoaded和load的区别

    一.概念 DOMContentLoaded 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表.图像和子框架的完成加载. load loa ...

  2. 2018-8-10-dotnet-core-编程规范

    title author date CreateTime categories dotnet core 编程规范 lindexi 2018-08-10 19:16:52 +0800 2018-05-0 ...

  3. PAT Advanced 1077 Kuchiguse (20 分)

    The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...

  4. PAT Advanced 1035 Password (20 分)

    To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...

  5. libboost_regex 备份用时

    libboost_regex-vc100-mt-s-1_57.lib  //生成数据

  6. 【学习】018 Spring框架

    Spring的概述 Spring框架,可以解决对象创建以及对象之间依赖关系的一种框架. 且可以和其他框架一起使用:Spring与Struts,  Spring与hibernate (起到整合(粘合)作 ...

  7. spring bean的生命周期与作用域

    bean的作用域 singleton:单例模式,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象. prototype:原型模式,每次通过Spri ...

  8. PHP程序员要看的书单

    想提升自己,还得多看书!多看书!多看书! 下面是我收集到的一些PHP程序员应该看得书单及在线教程,自己也没有全部看完.共勉吧! Github地址:https://github.com/52fhy/ph ...

  9. layui table 分页 记住之前勾选的数据

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. luoguP1445 [Violet]樱花

    链接P1445 [Violet]樱花 求方程 \(\frac {1}{X}+\frac {1}{Y}=\frac {1}{N!}\) 的正整数解的组数,其中\(N≤10^6\),模\(10^9+7\) ...