【Combine Collection】| AcWing 240. Food Chain

240. Food Chain

There are three types of animals in the animal kingdom, A, B, and C. The food chain of these three types of animals forms an interesting ring.

A eats B, B eats C, and C eats A.

There are currently N animals, numbered from 1 to N.

Each animal is one of A, B, and C, but we don't know which one it is.

Some people describe the food chain relationship formed by these N animals in two ways:

The first statement is 1 XY, which means that X and Y are of the same kind.

The second argument is 2 XY, which means X eats Y.

This person uses the above two statements to say K sentences to N animals. Some of these K sentences are true and some are false.

When a sentence satisfies one of the following three items, the sentence is false, otherwise it is true.

The current words conflict with some of the previous true words, which is a lie; in the
current words X or Y is greater than N, it is a lie; the
current words mean that X eats X, which is a lie.
Your task is to output the total number of false words based on the given N and K sentences.

Input format The
first line is two integers N and K, separated by a space.

Each of the following K lines contains three positive integers D, X, Y, separated by a space between the two numbers, where D represents the type of argument.

If D=1, it means that X and Y are of the same kind.

If D=2, it means X eats Y.

The output format
has only one integer, which represents the number of lies.

Data range
1≤N≤50000,
0≤K≤100000

Input sample:

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

Code

#include <iostream>
#define read(x) scanf("%d",&x)

using namespace std;

const int N=5e4+10;
int pre[N],dis[N];

int find(int x)
{
    
    
    if (pre[x]!=x) {
    
    
        int t=pre[x];
        pre[x]=find(pre[x]);
        dis[x]= (dis[x]+dis[t])%3; 
    }
    return pre[x];
}

int main()
{
    
    
    int n,k;
    read(n),read(k);
    //初始化并查集,动物编号从1开始
    for (int i=1;i<=N;i++) pre[i]=i;
    //开始输入并判断
    int s,x,y;
    int res=0;
    while (k--) {
    
    
        read(s),read(x),read(y);
        s--;//我们规定的状态距离为0表示同类,距离为1表示x吃y,距离为2表示y吃x
            //输入的s为1表示同类,2表示x吃y,让s代替距离
        if ( x>n||y>n||(s&&(x==y)) ) {
    
    res++; continue;}
        int px=find(x),py=find(y);
        if (px!=py) {
    
     //x所在加入集合中y所在集合中
            pre[px]=py; dis[px]=(dis[y]+s-dis[x])%3;  //根据输入,要么是x吃y,要么是x和y同类,认为dis[x]>=dis[y]
        } else {
    
                                          //等式dis[x]+dis[px]-s和dis[y]模3同余
            if ((dis[x]-dis[y]-s)%3) res++;
        }
    }
    printf("%d",res);
    return 0;
}

Guess you like

Origin blog.csdn.net/HangHug_L/article/details/114625788