题目链接:https://ac.nowcoder.com/acm/problem/16884
题意:有N只动物,这些动物属于A、B、C的其中一种;已知A吃B、B吃C、C吃A。接着有K条信息,第一种:x和y是同类;第二种:x吃y。 问有多少条信息是假的?
思路:对于每只动物i创建3个元素i-A,i-B,i-C,并用3*N个元素建立并查集。
维护并查集:
第一种:x和y同类: unite(x-A,y-A),unite(x-B,y-B),unite(x-c,y-c);
第二种:x吃y: unite(x-A,y-B),unite(x-B,y-C),unite(x-C,y-A);
如果出现第i条信息发生冲突 则说明是假话,ans++;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=3e5+5; int par[MAXN]; int height[MAXN]; int N,K; void init(int n) { for(int i=1;i<=n;i++) { par[i]=i; height[i]=1; } }
int Find(int x) { if(par[x]==x) return x; else return par[x]=Find(par[x]); }
void unite(int x,int y) { x=Find(x); y=Find(y); if(x==y) return; if(height[x]<height[y]) { par[x]=y; } else { par[y]=x; if(height[x]==height[y]) height[x]++; } }
bool same(int x,int y) { return Find(x)==Find(y); }
void solve() { init(3*N); int ans=0; int t,x,y; for(int i=1;i<=K;i++) { scanf("%d%d%d",&t,&x,&y); if(x<=0||N<x||y<=0||N<y) {ans++;continue;} if(t==1) { if(same(x,y+N)||same(x,y+2*N)) ans++; else { unite(x,y); unite(x+N,y+N); unite(x+2*N,y+2*N); } } else { if(same(x,y)||same(x,y+2*N)) ans++; else { unite(x,y+N); unite(x+N,y+2*N); unite(x+2*N,y); } } } printf("%d\n",ans); }
int main(){ scanf("%d%d",&N,&K); solve(); return 0; }
|