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. Mysql逻辑架构介绍

    总体概览: 和其它数据库相比,MySQL有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用.主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离 ...

  2. git log 详解 以及代码量统计

    https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86% ...

  3. HTML与CSS中的定位个人分享

    定位 static - 默认值 (几乎不用,了解就可以) absolute - 绝对定位,不为元素预留空间,脱离文档流: 如果当前元素的父级元素是<body>元素的话 -> 是相对于 ...

  4. day04记

    useGeneratedKeys useGeneratedKeys这个只在insert语句中有效,正常情况下useGeneratedKeys默认为false 当useGeneratedKeys为tru ...

  5. hihocode 1584 : Bounce (找规律)(2017 北京网络赛G)

    题目链接 比赛时随便找了个规律,然后队友过了.不过那个规律具体细节还挺烦的.刚刚偶然看到Q巨在群里提到的他的一个思路,妙啊,很好理解,而且公式写起来也容易.OrzQ巨 #include<bits ...

  6. A1036

    输入n行不同学生的name性别id和成绩,输出成绩最高的女生名字和id,成绩最低的男生名字和id求出二者的差 如果有性别缺少,输出Absent并在结果行输出NA 注意变量不要搞混,可以用结构体……不过 ...

  7. JavaScript性能优化之小知识总结

    1.避免全局查找 在一个函数中会用到全局对象存储为局部变量来减少全局查找,因为访问局部变量的速度要比访问全局变量的速度更快些 2.定时器 如果针对的是不断运行的代码,不应该使用setTimeout,而 ...

  8. 【CF1252F】Regular Forestation(重心,树同构)

    题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵 n<=4000 思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同 预 ...

  9. 【CF1249D】Too Many Segments(贪心,set,vector)

    题意:给定n条线段和覆盖上限k,每条线段都覆盖了区间内的整点 问最少删掉几条线段能使所有的整点都被覆盖不超过k次 k<=n<=2e5,l[i],r[i]<=2e5 思路:比赛时候不会 ...

  10. UE4 Pro Tips(keeps updating)

    Consolidate 功能 :在工程范围内用一种资源替换另外一种或多种资源具体操作:同时在编辑器中选中两个或多个资源,右键>Asset Actions>Replace Reference ...