一个基础的并查集,因为有类似于循环的存在,所以用一个数组,3个区间去存(很巧妙),使得第一个区间吃第二个区间,第二个区间吃第三个区间,第三个区间吃第一个区间。
要注意,如果要对并查集赋值,一定要3个区间的关系均赋值到位。
#include
using namespace std;
const int MX=1e5+9;
int t[MX*3],n,k,order,x,y,ans=0;
int fin(int u){
return t[u]=(t[u]==u?u:fin(t[u]));
}
int same(int u,int v){
return fin(u)==fin(v);
}
void unite(int u,int v){
u=fin(u);
v=fin(v);
if( u<v )
t[v]=u;
else
t[u]=v;
}
int main()
{
// freopen("input.txt","r",stdin);
scanf("%d %d",&n,&k);
for( int i=1 ; i<=n*3 ; i++ )
t[i]=i;
while( k-- ){
scanf("%d %d %d",&order,&x,&y);
if( x>n || y>n || (order==2 && x==y ) || x<=0 || y<=0 ){
ans++;
continue;
}
if( order==1 ){
if( same(x,y+n) || same(x+n,y) )
ans++;
else{
unite(x,y);
unite(x+n,y+n);
unite(x+n*2,y+n*2);
}
}
else{
if( same(y,x+n) || same(x,y) )
ans++;
else{
unite(x,y+n);
unite(x+n,y+2*n);
unite(x+2*n,y);
}
}
}
printf("%d",ans);
return 0;
}