poj 1182 食物链

来源:互联网 发布:拓扑优化方面的书籍 编辑:程序博客网 时间:2024/06/02 06:12

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


0 0