题目描述
动物王国中有三类动物 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 真话
【胡乱分析】
用1~n表示动物,n+1~2n表示吃某动物的动物,2n+1到3n表示被吃的动物;如:a+n表示吃a的,a+2n表示吃b的;所以一开始在存fa[]和size[]的时候也是1~3n。余下的看代码。这次主要的问题是语文,把三类动物和n个动物弄混了。
1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<algorithm>
5 #include<cstring>
6 using namespace std;
7 const int M = 200000;
8 int fa[M],size[M];
9 int find(int x)
10 {
11 if(fa[x] != x) return fa[x] = find(fa[x]);
12 return fa[x];
13 }
14 void unionn(int x,int y)
15 {
16 x = find(x);
17 y = find(y);
18 if(x == y) return;//如果两个已经在同一个集合中了,就不用操作
19 else
20 {
21 if(size[x] > size[y])//小的往大的里合并
22 {
23 size[x] += size[y];
24 fa[y] = x;
25 }
26 else
27 {
28 size[y] += size[x];
29 fa[x] = y;
30 }
31 }
32 }
33 int main()
34 {
35 int n,k,d,a,b,ans = 0;
36 scanf("%d%d",&n,&k);
37 for(int i = 1;i <= 3 * n;i++)
38 {
39 fa[i] = i;
40 size[i] = 1;
41 }
42 for(int i = 1;i <= k;i++)
43 {
44 scanf("%d%d%d",&d,&a,&b);
45 if(a > n || b > n)//如果动物编号大于动物个数,则是假话
46 {
47 ans++;
48 }
49 else
50 {
51 if(d == 1)
52 {
53 if(find(a) == find(b + n) || find(a) == find(b + 2 * n)) ans++;//如果a和吃b的动物为一类,则a不可能跟b是同类;如果a和被b吃的是同类,他俩也不可能为同类
54 else//如果这句话是真的
55 {
56 unionn(a,b);//合并a,b为一类
57 unionn(a + n,b + n);//吃a的动物也吃b
58 unionn(a + 2 * n,b + 2 * n);//被a吃的动物也被b吃
59 }
60 }
61 else
62 {
63 if(find(a) == find(b) || find(a) == find(b + 2 * n)) ans++;//如果ab为一类或a与被b吃的是一类,则a不可能吃b
64 else
65 {
66 unionn(a,b + n);//a和吃b 的是一类
67 unionn(a + 2 * n,b);//被a吃的和b 是一类
68 unionn(a + n,b + 2 * n);//由于一共有三类动物,所以吃a的和被b吃的是一类。
69 }
70 }
71 }
72 }
73 printf("%d",ans);
74 return 0;
75 }