挑战程序设计上有解答的并查集好题。把事件作为元素进行合并,举例:若输入1 2 3,意思就是把2,3归为同一类,至于归于哪一类并不需要去讨论,则把2属于A,3属于A这两件事件归为一类;2属于B,3属于B这两件事归为一类;2属于C,3属于C这两件事归为一类;若输入 2 2 3,由于A吃B,B吃C,C吃A,就把2属于A,3属于B这两件事情归为一类;以此类推。当检测到当前情况与之前正确的情况不符合,则错误的情况数加1。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct node { int root; }nod[150010]; void initial(int n) { for(int i=1;i<=3*n;i++){ nod[i].root=i; } } int Find(int k) { if(k!=nod[k].root){ nod[k].root=Find(nod[k].root); } return nod[k].root; } void Union(int a,int b,int c,int d,int e,int f) { nod[Find(b)].root=Find(a); nod[Find(d)].root=Find(c); nod[Find(f)].root=Find(e); } int main() { int n,k; scanf("%d%d",&n,&k); initial(n); int ans=0; int cnt=1; for(int i=0;i<k;i++){ int q,a,b; scanf("%d%d%d",&q,&a,&b); if(a>n || b>n ||a<=0 || b<=0){ ans++; continue; } if(q==1){ if(Find(a)==Find(b+n) || Find(a)==Find(b+2*n)){ ans++; } else{ Union(a,b,a+n,b+n,a+2*n,b+2*n); } } else{ if(Find(a)==Find(b) || Find(a)==Find(b+2*n)){ ans++; } else{ Union(a,b+n,a+n,b+2*n,a+2*n,b); } } } printf("%d\n",ans); return 0; }