NOI2001 食物链 并查集
2016-07-01 10:27
375 查看
NOI2001食物链
动物王国中有三类动物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),输出假话的总数。Input
第一行是两个整数N和K,以一个空格分隔。 以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 若D=1,则表示X和Y是同类。 若D=2,则表示X吃Y。Output
只有一个整数,表示假话的数目。Sample Input
输入文件 对7句话的分析100 71 101 1 假话2 1 2 真话2 2 3 真话2 3 3 假话1 1 3 假话2 3 1 真话1 5 5 真话
Sample Output
3题解:非法的情况有三种,后两种很明显容易处理,读入的时候判断即可。第一种情况是处理集合之间是否冲突的问题,容易想到用并查集。对于第一种,我们分两种情况讨论。我们将N个点做2个虚构投影,即将fa数组扩大为3*n。fa[1~n]被fa[n+1~2n]吃 fa[n+1~2n]被fa[2n+1~3n]吃 fa[2n+1~3n] 被 fa[1~n] 吃当d=1时因为是合并,只需要判断 x是否被y吃、y是否被x吃( find(x+n)=find(y) find(x+2n)=fa(y) )若合法,将 (x,y) (x+n,y+n) (x+2n,y*2n) 合并;不合法则ans+1当d=2时判断 x是否被y吃(find(x+2n)=find(y)) 或 x和y是否同类 (find(x)=find(y))若合法,将(x+n,y) (x+2n,y+n) (x,y+2n)合并 不合法则inc(ans);
constmaxn=50001;varn,k,i,d,x,y,ans:longint;fa:array[1..maxn*3]of longint;f:boolean;function find(x:longint):longint;beginif fa[x]=x then exit(x);fa[x]:=find(fa[x]);find:=fa[x];end;procedure union(x,y:longint);varu,v:longint;beginu:=find(x);v:=find(y);if u<>v thenfa[u]:=v;end;procedure init;vari:longint;beginreadln(n,k);for i:=1 to 3*n dofa[i]:=i;end;begin// assign(input,'data3.in');reset(input);init;for i:=1 to k dobeginreadln(d,x,y);if (d=2)and(x=y) thenbegininc(ans);continue;end;if (x>n)or(y>n) thenbegininc(ans);continue;end;if d=1 thenbeginf:=false;if find(x+n)=find(y) then f:=true;if find(x+2*n)=find(y) then f:=true;if f=false thenbeginunion(x,y);union(x+n,y+n);union(x+2*n,y+2*n);endelse inc(ans);end;if d=2 thenbeginf:=false;if find(x)=find(y) then f:=true;if find(x+2*n)=find(y) then f:=true;if f=false thenbeginunion(x+n,y);union(x,y+n+n);union(x+n+n,y+n);endelse inc(ans);end;end;writeln(ans);end.
相关文章推荐
- 数据库SQL优化大总结之 百万级数据库优化方案
- androidpn+tomcat推送消息源码流程分析
- fdisk
- 实习杂记(27):如何解决Java.lang.NoClassDefFoundError
- 安卓中的事件与消费原理
- 栈和队列-剑指offer
- 笔记
- mysql.user字段含义
- vim保存文件时,生成.un~文件
- 最新版 VS2015|Visual Studio Enterprise 2015简体中文版(企业版)
- 【jmeter】JMeter函数学习
- 监控Linux性能的18个命令行工具
- css 这种小细节不错
- Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
- Javascript异步编程的4种方法
- JDK1.8安装配置
- 设计模式C++实现(1)——工厂模式
- Print Article[HDU 3507]
- GB28181的局限性
- 指针函数与函数指针、指针的指针与纸箱指针数组的指针