Q1:怎么判断X和Y是不是同类?
A:判断这俩是不是在一个集合中,如果在同一个集合中,那么判断X到祖先节点的距离D[X]和D[Y]到祖先节点的距离是否有D[X]%3=D[Y]%3,也就是3同余
若果是,那么是同类。如果X和Y不在一个集合里面,那么把X和Y合并到一个集合里面。修改p[x]
和d[px]
接着问题来了,如何正确修改p[x]
和d[px]
?
Q2:怎么判断X吃Y?
A:判断这俩是不是在一个集合中,如果在同一个集合中,那么判断
(
d
[
X
]
+
1
)
%
3
=
d
[
Y
]
%
3
(d[X]+1)\%3=d[Y]\%3
(d[X]+1)%3=d[Y]%3,如果是,那么X吃Y,若X和Y不在一个集合中那么合并X和Y,修改p[px]
,d[px]
#include<iostream>
#include<string>
#define LEN 100086
using namespace std;
int N,K,p[LEN],d[LEN];
int find(int x){
if(p[x]!=x){
int t=find(p[x]);
d[x]+=d[p[x]];
p[x]=t;
}
return p[x];
}
int main(){
cin>>N>>K;
int res=0;//假话个数
for(int i=1;i<=N;++i){
p[i]=i;
}
while(K--){
int D,X,Y;
cin>>D>>X>>Y;
if(X>N||Y>N) {
++res;
continue;
}
if(D==2&&X==Y) {
++res;
continue;
}
int px=find(X),py=find(Y);
if(D==1){
if(px==py&&(d[X]-d[Y])%3){
res++;
}
else if(px!=py){
p[px]=py;
d[px]=d[Y]-d[X];
}
}
else if(D==2){
if(px==py&&(d[X]-d[Y]-1)%3){
res++;
}else if(px!=py){
p[px]=py;
d[px]=d[Y]+1-d[X];
}
}
}
cout<<res<<endl;
return 0;
}