poj 1182 Food chain

There are three groups of animals A, B, and C in the animal kingdom, and the food chains of these three groups form an interesting loop. A eats B, B eats C, and C eats A.
There are N animals, numbered 1-N. Every animal is one of A, B, and C, but we don't know which one it is.
Some people describe the relationship of the food chain formed by these N animals in two ways:
The first way is "1 X Y", which means that X and Y are the same kind.
The second way is "2 X Y", which means X eats Y.
This person uses the above two statements to say K sentences sentence after sentence to N animals. Some of these K sentences are true and some are false. When a sentence satisfies one of the following three conditions, the sentence is false, otherwise it is true.
1) If the current word conflicts with some previous true words, it is false;
2) If X or Y in the current word is larger than N, it is false;
3) If the current word means X eats X, it is false.
Your task is to output the total number of falsehoods given N (1 <= N <= 50,000) and K sentences (0 <= K <= 100,000).
Input
The first line is two integers N and K, separated by a space.
Each of the following K lines is three positive integers D, X, Y, separated by a space, where D represents the type of argument.
If D=1, it means that X and Y are the same.
If D=2, it means that X eats Y.
Output
There is only one integer, representing the number of falsehoods.
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
3Learn 
to take the weight and check the set.
Code:
#include <iostream> 
#include <cstring> 
#include <cstdio> 
#include <map>
 #define Max 50005
 using  namespace std;
 int n,k,f[Max],tag[Max],c;
 /// f record The relationship between the parent node tag record and the parent node 0 means the same kind 1 means eating the node 2 means being eaten by the node
 /// eg 1 eats 2 tag[1] = 0 (initially and owns the same kind), tag[2] = 1; 2 eats 3 tag[2] = 1, tag[3] = 1, tag[3] = 2 after getf, because 3 eats 1; 34 similar tag[3] = 2, tag[4] = 0, After getf tag[4] = 2
 /// Now tag[1] = 0, tag[2] = 1, tag[3] = 2, tag[4] = 2
 /// At this time, judge 1 to eat 2 (tag [2] - tag[1] + 3) % 3 = 1 is satisfied; judge that 4 eats 2 (tag[2] - tag[4] + 3) % 3 = 2, the result is that 4 is eaten by 2
 /// Observe if Two points x, y are the same parent, list the relationship between xy and the parent
 ///1. xy are all eaten tag[x] = 1, tag[y] = 1, at this time, the tag'[y] for x in the same calculation of xy should be 0 to satisfy (tag[y] - tag[x] + 3 ) % 3 = 0
 /// 2.x is eaten by y tag[x] = 1, tag[y] = 2, y is eaten by x, tag'[y] = (tag[y] - tag[x ] + 3) % 3 = 1 (the two exchanges are similar)
 /// 3.x is eaten by y tag[x] = 0, tag[y] = 2, y eats x, tag'[y] = (tag [y] - tag[x] + 3) % 3 = 2 (the two exchanges are similar)
 /// 4.x y of the same kind is eaten tag[x] = 0, tag[y] = 1, y is eaten by x, tag'[y] = (tag[y] - tag[x] + 3) % 3 = 1 (the two exchanges are similar)
 /// 5. It is obvious
 that both xy are of the same type. /// 6. It is eaten by both xy and xy. Similar 
void init()
{
    for(int i = 1;i <= n;i ++)
    {
        f[i] = i; /// The initial parent is himself 
    }
}
int getf( int a) /// Root compression 
{
     if (f[a] != a)
    {
        int t = getf(f[a]); /// If you let f[a] = root directly, the next step is meaningless, tag[root] = 0 
        tag[a] = (tag[a] + tag[f [a]]) % 3 ; /// According to the relationship between a and the parent and the relationship between the parent and the root, the relationship between a and the root is transformed into the relationship between a and the root (the rule is easy to find) 
        f[a] = t;
    }
    return f[a];
}
int mer( int d, int a, int b) /// d = 0 peer d = 1 a eats b 
{
     int aa = getf(a);
     int bb = getf(b);
     if (aa == bb) / // means in the same food chain 
    {
         if ((tag[b] - tag[a] + 3 ) % 3 != d) return  0 ;
         return  1 ;
    }
    day[bb] = (day[a] - day[b] + 3 + d) % 3 ;
    f[bb] = aa;
    return 1;
}
intmain ()
{
    int d,a,b;
    scanf("%d%d",&n,&k);
    init();
    for(int i = 0;i < k;i ++)
    {
        scanf( " %d%d%d " ,&d,&a,& b);
         if (a > n || b > n || !mer(d - 1 ,a,b))c ++; /// Exceeding the range is a lie that does not match the original or does not match the truth 
    }
    printf("%d",c);
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324804122&siteId=291194637