题意:有三种动物:A、B、C,其中A吃B,B吃C,C吃A构成环,给N只动物,不知道每只种类,但有K个说法,1表示X与Y同类,2表示X吃Y,其中X不能吃X自己,且X、Y不能超过N,求出这些说法里错误的个数
思路:将A、B、C编号为x、x+n、x+2 * n,A吃B表示为x与y+n,x+n与y+2 * n,x+2 * n与y在同一集合里,AB同类表示为x与y、x+n与y+n、x+2 * n与y+2 * n在同一集合里,判断是否同类时,只需判断当前是否X吃Y或者Y吃X;判断是否X吃Y时,只需判断XY是否同类或者在当前食物链内Y吃X即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 3e5+5;
const int inf = 0x3f3f3f3f;
int n, k, u[maxn];
int ufind(int x)
{
if (u[x] != x)
u[x] = ufind(u[x]);
return u[x];
}
void unite(int x, int y)
{
u[ufind(x)] = ufind(y);
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= 3*n; i++) {
u[i] = i;
}
int ans = 0;
for (int i = 0; i < k; i++) {
int op, x, y;
scanf("%d%d%d", &op, &x, &y);
if (x > n || y > n || x <= 0 || y <= 0) {
ans++;
continue;
}
if (op == 1) {
if (ufind(x) == ufind(y+n) || ufind(x) == ufind(y+2*n)) {
ans++;
continue;
}
unite(x, y);
unite(x+n, y+n);
unite(x+2*n, y+2*n);
} else if (op == 2) {
if (ufind(x) == ufind(y+2*n) || ufind(x) == ufind(y)) {
ans++;
continue;
}
unite(x, y+n);
unite(x+n, y+2*n);
unite(x+2*n, y);
}
}
printf("%d\n", ans);
return 0;
}