这个题目需要注意好几个地方,最重要的方法就是向量法确定关系转移,而关系转移又需要退到两种情况,第一种,是Find的时候,进行路径压缩的时候,另一种是两个点属于不同的树的时候,而且为了便于操作,我们需要设置0 为 相同(与题目中的关系1相同), 1 为 a吃b(与题目中的关系2对应)。3对应b吃a
代码如下,注意关系,不能随意推到,因为有方向关系:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std ;
#define MAX 50005
struct Node{
int f ;
int r ;
};
int sum ;
Node pre[MAX];
int Find(int x){
int temp ;
if(x != pre[x].f )
{
temp = pre[x].f;
pre[x].f = Find(temp);
pre[x].r = (pre[x].r + pre[temp].r)%3;
}
return pre[x].f;
}
int main(){
sum = 0 ;
int nums , r_num , R , X,Y;
cin >> nums >> r_num ;
for(int i = 0 ; i <=nums ; i ++ )
{
pre[i].f= i ;
pre[i].r =0 ;
}
for(int i = 0 ; i < r_num ; i++ )
{
cin >> R >> X >> Y ;
if(X>nums||Y>nums)
{
sum ++ ;
continue ;
}
if(X==Y&&R==2)
{
sum ++ ;
continue ;
}
int fx = Find(X);
int fy = Find(Y);
if(fx == fy)
{
if(R ==1&&pre[X].r != pre[Y].r)
{
sum ++ ;
continue ;
}
else if(R == 2 &&(3 - pre[Y].r + pre[X].r)%3 != R -1)
{
//此处应为 (3 - pre[Y].r + pre[X].r)%3 != R-1, 因为在合并时是将x合并到y
sum ++ ;
continue ;
}
}else{
pre[fx].f=fy ;
pre[fx].r = (3+ R-1 + pre[Y].r - pre[X].r)%3;
}
}
cout << sum <<endl;
return 0 ;
}