题解
将数组fa分为三部分:
集合A[1 ~ n],集合B[n+1 ~ 2n] ,集合C[2n+1 ~ 3n]
同类操作:同一集合内部进行合并
敌对操作:不同集合合并,且有方向,比如说,u吃v,则写成 fa[v] = u,而不可以写反
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
//种类并查集
//前提 与前面冲突即为假话
int n,m;
int fa[N*3];
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main(){
cin>>n>>m;
for (int i = 1; i <= n*3; ++i) {
fa[i]=i;
}
int cnt=0;//统计错误答案
for (int i = 1,op,u,v; i <= m; ++i) {
cin>>op>>u>>v;
if(u>n||v>n){
cnt++;
continue;
}
if(op==1){//同类
if(find(u+n)==find(v) || find(u)==find(v+n))
//不同集合被合并 说明应该是竞争关系
cnt++;
else{
//同一集合内合并
fa[find(u)]=find(v);
fa[find(u+n)]=find(v+n);
fa[find(u+n+n)]=find(v+n+n);
}
}else{//竞争关系 u吃v == fa[v]=u
if(find(u)==find(v)||find(u)==find(v+n))
//同一集合内被合并 or 竞争关系颠倒
cnt++;
else {
fa[find(u+n)]=find(v);
fa[find(u+n+n)]=find(v+n);
fa[find(u)]=find(v+n+n);
}
}
}
printf("%d", cnt);
return 0;
}