POJ1182 Food Chain (and collect good questions)

Topic link

Description

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 one is "1 X Y", which means that X and Y are of the same kind.
The second argument is "2 X Y", which means X eats Y.
This person uses the above two statements to say K sentences to N animals one after another. 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.
1) The current words conflict with some previous true words, which is a lie;
2) The current words X or Y is greater than N, which is a lie;
3) The current words mean that X eats X, which is a lie.
Your task is to output the total number of lies based on a 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 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.

Output

There is only one integer, which represents the number of lies.

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

Ideas

Use a 3*N size array to correspond to the three animals A, B, and C respectively. Use and search for different relationships to establish contacts. If conflicts occur, record them. (See code comments for details)

Code

#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
//#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
int n,k,x[maxn],y[maxn],r[maxn],pre[maxn];
int find(int x)
{
    
    
	if(x==pre[x])
        return x;
    else
        return pre[x]=find(pre[x]);
}
void unite(int a,int b)
{
    
    
	
    int fa=find(a);
    int fb=find(b);
    if(fa!=fb)
        pre[fa]=fb;
}
bool judge(int a,int b)
{
    
    
	return find(a)==find(b);
}
int main()
{
    
    
	scanf("%d%d",&n,&k); 
	for(int i=0;i<k;i++)
		scanf("%d%d%d",&r[i],&x[i],&y[i]);//说法种类,编号 
	for(int i=0;i<=n;i++)
		pre[i]=i;
	int ans=0;
	for(int i=0;i<k;i++)
	{
    
    
		int num=r[i];
		int a=x[i]-1,b=y[i]-1;
		if(a<0||a>n-1||b<0||b>n-1)
		{
    
    
			ans++;
			continue;
		}//条件越界 
		if(num==1)//a和b是同类
		{
    
    
			if(judge(a,b+n)||judge(a,b+2*n))
				ans++;//非同类动物在同一集合中,产生矛盾
			else
			{
    
    
				unite(a,b);//A类合并
				unite(a+n,b+n);//B类合并
				unite(a+2*n,b+2*n);//C类合并 
			}
		}
		else
		{
    
    
			if(judge(a,b)||judge(a,b+2*n))
				ans++;//a,b已是同类或出现逆食物链的情况 
			else
			{
    
    
				unite(a,b+n);//A吃B 
				unite(a+n,b+2*n);//B吃C 
				unite(a+2*n,b);//C吃A 
			}
		}
	}
	printf("%d\n",ans);
    return 0;
}

Guess you like

Origin blog.csdn.net/WTMDNM_/article/details/108802999