刚开始用0,-1,1来表示和父节点的关系,写了好久都没写出来
然后用0,1,2来表示和父节点的关系,写的相对于原来的方法来说轻松了很多
(0表示和父节点是同类,1表示吃父节点,2表示被父节点吃)
在一个三元环上走,0表示不动,1是前进一步,2是退一步(因为模3意义下2等于-1)
这样的话就不用去可以的画表去推到底是什么和什么关系,只要%3就可以给你自动处理好了
写出来的时候也是感觉十分的神奇
以及这个题不能强行多组输入,会迷之WA(
-------------------------here is my code--------------
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 51234;
int arr[maxn];
int val[maxn]; // =0 same / =1 eat rot/ =2 be eat
void init(int n){
for(int i=0;i<=n;i++){
arr[i]=i,val[i]=0;
}
}
int fnd(int x){
if(arr[x]==x) return x;
else{
int fa = arr[x];
arr[x] = fnd(arr[x]);
val[x] = (val[x]+val[fa])%3;
return arr[x];
}
}
bool join(int x,int y,int eat){
int rx = fnd(x);
int ry = fnd(y);
if(rx==ry){
return eat == (val[x]-val[y]+3)%3;
}
else{
arr[rx]=ry;
val[rx]= (3-val[x]+eat+val[y])%3;
return true;
}
}
void out(int *s,int n){
for(int i=1;i<=n;i++)
printf(i<n?"%d ":"%d\n",s[i]);
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
init(n);
int x,y,ea;
int ans =0;
while(m--){
scanf("%d %d %d",&ea,&x,&y);
ea--;
if(x>n || x<=0 || y<=0 || y>n || join(x,y,ea)==false) ans++;
}
printf("%d\n",ans);
return 0;
}