POJ 1182
阿新 • • 發佈:2020-07-15
重新做了一下這道並查集的題目,關鍵要點是抓住這種迴圈的關係和模運算的通性,進而利用加權並查集
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 5e4+3; const int maxk = 1e5+3; // tp 0: same 1: eat fa 2: eaten by fa int tp[maxn], fa[maxn]; int Find(int x) { if (x== fa[x]){ return x; } int tf= fa[x]; fa[x]= Find(tf); tp[x]= (tp[tf]+tp[x])%3; return fa[x]; } void MakeSet(int n) { for (int i= 1; i<= n; ++i){ fa[i]= i; } } void Init(int n) { memset(tp, 0, sizeof(tp)); MakeSet(n); } int Union(int op, int a, int b) { int pa= Find(a); int pb= Find(b); if (pa== pb){ if (tp[a]== tp[b] && 1== op){ return 1; } if ((1== ((3+tp[a]-tp[b])%3)) && 2== op){ return 1; } return 0; } fa[pa]= pb; tp[pa]= (op-1+tp[b]+3-tp[a])%3; return 1; } int main() { int n, k, ans= 0, op, x, y; scanf("%d %d", &n, &k); Init(n); for (int i= 0; i< k; ++i){ scanf("%d %d %d", &op, &x, &y); if (x> n || y> n){ ++ans; continue; } if (!Union(op, x, y)){ ++ans; } } cout<<ans<<endl; return 0; }