[poj1182]食物链
题意:a吃b,b吃c,c吃a,给定一系列条件,判断出错的个数。
解题关键:种类并查集。关键是向量的合成。
设0:a与par[a]同类,1:a吃par[a] 2:a被par[a]吃
( 儿子relation + 父亲relation ) % 3 = 儿子对爷爷的relation
利用这个公式,对向量进行推导即可。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; const int maxn=50010; int par[maxn],rank[maxn]; void init(int n){ for(int i=0;i<=n;i++){ par[i]=i; rank[i]=0; } } int find1(int x){ if(x==par[x]) return par[x]; int y=find1(par[x]); rank[x]=(rank[x]+rank[par[x]])%3; return par[x]=y; } //环中向量的合成 int unite(int typ,int x,int y){ int x1=find1(x); int y1=find1(y); if(x1==y1){ if((rank[x]-rank[y]+3)%3==typ-1) return 0;//-rank[y]-(-rank[x]) return 1; } par[x1]=y1; rank[x1]=(typ-1+rank[y]-rank[x]+3)%3; return 0; } int main(){ int n,k,ans,typ,smt1,smt2; scanf("%d%d",&n,&k); init(n); ans=0; for(int i=0;i<k;i++){ scanf("%d%d%d",&typ,&smt1,&smt2);//保证不同 if(smt1==smt2&&typ==2) ans++; else if(smt1>n||smt2>n) ans++; else ans+=unite(typ,smt1,smt2); } printf("%d\n",ans); return 0; }