Description

动物王国中有三类动物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

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

Sample Output

3


解题思路:这道题要我们得出假话的数目,如果这就话和之前的话冲突就是假话。我开始没有什么思路,看了看样例,随手画出了图,感觉像是图论的东西,但其实再仔细想想,其实这是一种状态的划分!!!比如说a和b是同类关系,那就把a和b划分到一个集合中,之后再说a和b是捕食关系一定是假话了。但是这道题的问题在于某一个动物在食物链中的角色不是一定的,一个物种可能作为捕食者也可能是被捕食者,还有可能给出同类之间的关系,那该怎么办呢?将所扮演的三种状态全都表示出来。列如,对于物种x,x代表A类,x+n代表B类,x+2n代表c类,其中A吃B,B吃C,C吃A。

对于两个动物如果是同类关系,那么一定不存在捕食和被捕食关系;如果存在捕食关系,那么一定不存在被捕食和同类关系。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MAX 50010*3
 5 using namespace std;
 6 int pre[MAX];
 7 int Find(int x)
 8 {
 9     int a;
10     a=x;
11     while(pre[a]!=a)
12     {
13         a=pre[a];
14     }
15     return a;
16 }
17 void Union(int root1,int root2)
18 {
19     int x,y;
20     x=Find(root1);
21     y=Find(root2);
22     if(x!=y)
23     {
24         pre[x]=y;
25     }
26 }
27 int Same(int x,int y)///判断两个物种是否有关系
28 {
29     return Find(x)==Find(y);
30 }
31 int main()
32 {
33     int n,m,i,counts;
34     int a,b,q;
35     scanf("%d%d",&n,&m);
36     counts=0;
37     for(i=1;i<=n*3;i++)///开三倍的数组
38     {
39         pre[i]=i;
40     }
41     for(i=1;i<=m;i++)
42     {
43         scanf("%d%d%d",&q,&a,&b);
44         if(a<1||a>n||b<1||b>n)///输入的数不合法为假话
45         {
46             counts++;
47             continue;
48         }
49         if(q==1)
50         {
51             if(Same(a,b+n)||Same(a,b+2*n))///存在捕食关系或者被捕食关系
52             {
53                 counts++;
54             }
55             else///建立同类关系
56             {
57                 Union(a,b);
58                 Union(a+n,b+n);
59                 Union(a+2*n,b+2*n);
60             }
61         }
62         else if(q==2)
63         {
64             if(Same(a,b)||Same(a,b+2*n))///存在同类或者被捕食关系
65             {
66                 counts++;
67             }
68             else///建立所有的捕食关系
69             {
70                 Union(a,b+n);
71                 Union(a+n,b+2*n);
72                 Union(a+2*n,b);
73             }
74         }
75     }
76     printf("%d\n",counts);
77     return 0;
78 }

 

 

作者:王陸
 

-------------------------------------------

个性签名:罔谈彼短,靡持己长。做一个谦逊爱学的人!