题意:
有一串关系:
- 1 x y,表示x和y是同类。
- 2 x y,表示x吃y。
这串关系中,如果x吃y,y吃z,那么z必定吃x,形成一个环。
现在给定k个关系,问有几个关系是错误的。
分析:
扩展域并查集,将一个点分成三个点,分别判断属于不同类别的点之间是否满足一定约束关系。
代码:
#include <bits/stdc++.h> using namespace std; constexpr int mod = 1e9 +7; //constexpr int mod2 = 998244353; constexpr int MAXNe5 = 1e5 +7; constexpr int MAXNe6 = 1e6 + 7; typedef long long ll; #pragma region inline long long read() { char c = getchar();long long flag = 1, ans = 0; while(c < '0' || c > '9'){if(c == '-') flag = -1; c = getchar();} while(c >= '0' && c <= '9'){ans = ans * 10 + c - '0'; c = getchar();} return (ans * flag); } #pragma endregion // C'est la vie int fa[MAXNe6]; void init() { for(int i = 1; i < MAXNe6; ++ i) fa[i] = i; } int find(int x) { return (fa[x] == x) ? x : fa[x] = find(fa[x]); } void merge(int x, int y) { fa[find(x)] = find(y); } int main() { int n = read(), k = read(), ans = 0; init(); while(k --) { int d, x, y; cin >> d >> x >> y; if(x > n || y > n || (d == 2 && x == y)) ans ++; else { if(d == 1) { int fax = find(x), fay = find(y); int fax2 = find(x + n), fay2 = find(y + n); if(fax2 == fay || fay2 == fax) ans ++; else { merge(x, y); merge(x + n, y + n); merge(x + 2 * n, y + 2 * n); } } else { int fax = find(x), fay = find(y); int fax2 = find(x + n), fay2 = find(y + n); if(fax == fay || fax == fay2) ans ++; else { merge(x + n, y); merge(x + 2 * n, y + n); merge(y + 2 * n, x); } } } } cout << ans << endl; #ifndef ONLINE_JUDGE system("pause"); #endif }