poj 1182 食物链

刚开始用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;
}


你可能感兴趣的:(poj 1182 食物链)