洛谷P2024 食物链

挺神奇

题目描述

动物王国中有三类动物 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 句话有的是真

的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

• 当前的话与前面的某些真的话冲突,就是假话

• 当前的话中 X 或 Y 比 N 大,就是假话

• 当前的话表示 X 吃 X,就是假话

你的任务是根据给定的 N 和 K 句话,输出假话的总数。

输入输出格式

输入格式:

从 eat.in 中输入数据

第一行两个整数,N,K,表示有 N 个动物,K 句话。

第二行开始每行一句话(按照题目要求,见样例)

输出格式:

输出到 eat.out 中

一行,一个整数,表示假话的总数。

输入输出样例

输入样例#1:

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

输出样例#1:

3

说明

1 ≤ N ≤ 5 ∗ 10^4

1 ≤ K ≤ 10^5

并查集

学习之前做过的关押罪犯(NOIP2010,洛谷P1525)的“镜像”思想,开了三个并查集。对于一个结点x:  x集表示同类,x+n集表示x吃的动物集,x+2n表示吃x的动物集

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=50010;
 9 int n;
10 int f[mxn*3];
11 //f[x]表示x的同类集  f[x+n]表示x吃的动物集 f[x+2n]表示吃x的动物集
12 int k;
13 int ans=0;
14 int find(int x){
15     if(f[x]==x)return x;
16     else return f[x]=find(f[x]);
17 }
18 void hb(int x,int y){
19     int fx=find(x);
20     int fy=find(y);
21     if(fx!=fy) f[fx]=fy;
22     return;
23 }
24 bool pd(int a,int x,int y){
25     if(x>n || y>n ||x<1 || y<1)return false;//x或y大于n是假话
26     if(a==1){//同类
27
28         //int fx1=find(x+n);//吃x的集
29         if(find(x+n)==find(y) || find(x+2*n)==find(y))return false;
30         hb(x,y);
31         hb(x+n,y+n);
32         hb(x+2*n,y+2*n);
33         //如果是真话,合并为同类
34     }
35     if(a==2){//非同类
36         if(x==y)return false;//自己吃自己是假话
37         if(find(x)==find(y) || find(x+2*n)==find(y))return false;
38         hb(y,x+n);
39         hb(y+2*n,x);
40         hb(x+2*n,y+n);
41     }
42     return true;
43 }
44 int main(){
45     int c;
46     int x,y;
47     scanf("%d%d",&n,&k);
48     int i,j;
49     int len=n*3;
50     for(i=1;i<=len;i++)f[i]=i;//初始化
51     for(i=1;i<=k;i++){
52         scanf("%d%d%d",&c,&x,&y);
53         if(!pd(c,x,y))ans++;
54     }
55     printf("%d\n",ans);
56     return 0;
57 }
时间: 2024-12-28 05:47:15

洛谷P2024 食物链的相关文章

洛谷 P2024 食物链 POJ 1182 Label:并查集Turbo

题目描述 动物王国中有三类动物 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 句话有的是真 的,有的是假的.当

做题记录:P2024 食物链(洛谷)

P2024 食物链 /*思路:并查集,因为一开始我们并不知道每一只动物是哪一个种类的, 所以我们干脆建立三倍于n的空间,1~n这三分之一用来存第i只动物是A 的情况,n+1~2n这三分之一用来存第(i-n)只动物是B的情况,2n+1~3n这 三分之一用来存这只动物是C的情况.对于每一句话给出的关系,我们并 不知道其中的两个动物分别是属于哪一个种类的,所以我们就把每一种情 况都处理一遍.当两个属于同一个区间的动物被合并时,就代表它们是同 一个种类的:当两个属于不同区间的动物被合并时,就代表作为父节

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可

洛谷教主花园dp

洛谷-教主的花园-动态规划 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢3种树,这3种树的高度分别为10,20,30.教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最高. 输入输出格式 输入格式: 输入文件garden.in的第1行为一个正整数n,表示需要种的

洛谷 P2801 教主的魔法 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=2801 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不

洛谷P1466 集合 Subset Sums

洛谷P1466 集合 Subset Sums这题可以看成是背包问题 用空间为 1--n 的物品恰好填充总空间一半的空间 有几种方案 01 背包问题 1.注意因为两个交换一下算同一种方案,所以最终 要 f [ v ] / 2 2.要开 long long 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string&g

洛谷P1160 队列安排 链表

洛谷P1160 队列安排   链表 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <string> 6 #include <algorithm> 7 #include <iomanip> 8 #include <iostream> 9 using namespace std

洛谷 P3367 并查集模板

#include<cstdio> using namespace std; int n,m,p; int father[2000001]; int find(int x) { if(father[x]!=x) father[x]=find(father[x]); return father[x]; } void unionn(int i,int j) { father[j]=i; } int main() { scanf("%d%d",&n,&m); for