Problem-solving ideas
Alas, at the beginning, I understood the meaning of the question incorrectly and typed a naked one and checked it. . . I'm too vegetable ah ah ah ah
The giants said that this question seems to have two methods:
Algorithm 1 : Expand the domain and find the set
Introduce a new extension of union search set: extended domain union search set.
This approach uses the classic idea in graph theory: split points, that is, when each node in the graph needs to represent multiple information, each node is split into multiple points, and each point that is split represents the origin. Part of the information.
Back to this question, we consider to classify animals according to the relationship between eating and being eaten: xxTake x animals as an example, introduce virtual animalsx + n x+nx+n meansxxx eating animals, introduce virtual animalsx + 2 ∗ n x+2*nx+2∗n meansxxx Animals that eat, put the same kind of animals in the same collection, which can be used and checked for maintenance.
The operation method of merging and searching sets is as follows:
When the given x and y are the same, merge xxx和yyThe set where y is located, mergex + n x + nx+n和y + n y + nY+Set where n is, mergex + 2 ∗ n x+2*nx+2∗n和y + 2 ∗ n y + 2 * nY+2∗The collection where n is located.
Judge the lie: express xx in the words givenx和yyy is the same kind as an example, ifxx isobtained beforex和y + n y + nY+n (iexxx and eatyyy ’s animals are of the same kind) or,xxx和y + 2 ∗ n y + 2 * nY+2∗n (that is, x and the animal eaten by y are of the same kind) can obviously be judged as false. xxx吃yyThe same is true for y .
The advantages of this algorithm obviously reduce the difficulty of thinking and the difficulty of code, but the price it pays is more space and a larger time complexity constant, and the scope of application is not weighted and extensive.
Algorithm 2 : Weighted and search set
Get a very complicated side rights and the like, and then take the modulus and set up a bunch of formulas. So, since I'm too lazy haha just did not play this way. (But I found a very good blog to make up for my crime: Solution Two
PS: Be careful to judge xx firstx或yyy is greater thannnn andxxx equalsyyy case
Code
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
using namespace std;
int n,k,fa[150010],w,x,y,ans;
int find(int x){
if(fa[x]!=x)
return fa[x]=find(fa[x]);
else return fa[x];
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=3*n;i++)//i+n表示天敌,i+2*n表示猎物
fa[i]=i;
while(k--)
{
scanf("%d%d%d",&w,&x,&y);
if(x>n||y>n)
{
ans++;
continue;
}
int xx=find(x),yy=find(y),sx=find(x+n),sy=find(y+n),tx=find(x+2*n),ty=find(y+2*n);
//xx,yy表示x和y的同类,sx,sy表示x和y的天敌,tx,ty表示x和y的猎物
if(w==1)
{
if(xx==sy||xx==ty){
//说是同类,却是天敌或猎物,就是假
ans++;
continue;
}
else fa[xx]=yy,fa[sx]=sy,fa[tx]=ty;
}
if(w==2)
{
if(xx==yy||sx==yy)//说是x吃y,却是同类或y吃x,就是假
{
ans++;
continue;
}
else fa[xx]=sy,fa[sx]=ty,fa[tx]=yy;//x的同类是y的天敌,x的天敌是y的猎物,x的猎物是y的同类
}
}
printf("%d",ans);
}