思路:
- 基础种类并查集,注意取余,+3 。
- 读到文件尾会 WA,真是 … 。
总结:
- 逻辑判断类题,当同属于同一集合(头元素相同)时进行判断;不属于同一集合时,合并。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 50005;
int N,K;
int ans;
int par[maxn];
int val[maxn];
void INIT(){
ans = 0;
memset(par , -1 , sizeof(par)) ;
memset(val , 0 , sizeof(val)) ;
return ;
}
int FIND(int i){
if(par[i] == -1)
return i;
int temp = par[i];
par[i] = FIND(par[i]);
val[i] = (val[temp] + val[i])%3;
return par[i];
}
void UNION(int w,int l,int r,int parl,int parr){
par[parr] = parl;
val[parr] = (val[l] + w - val[r] + 3) % 3;
return ;
}
int main(){
cin>>N>>K;
INIT();
while(K--){
int type ;
int l , r;
scanf("%d%d%d" , &type , &l , &r);
if(l>N || r>N || l<1 || r<1 || (type == 2 && l == r)){
ans++ ;
continue;
}
int parl = FIND(l);
int parr = FIND(r);
if(type == 1){
if(parr == parl)
if(val[l] != val[r])
ans++;
else ;
else
UNION(0 , l , r , parl , parr);
}
else{
if(parr == parl)
if((val[l] + 1)%3 != val[r])
ans++;
else ;
else
UNION(1 , l , r , parl , parr);
}
}
cout<<ans<<endl;
return 0;
}