题目链接:点击打开链接
思路:并查集判断是否有关系
类型一个三种
#include<iostream>
#include<string>
using namespace std;
const int N = 500005;
int father[N];
int sum = 0;
int d[N] = { 0 };//代表与根节点的距离,有0,1,2三种
int n;
int find(int x) {//find时更新距离
if (x != father[x]) {
int pre = father[x];
father[x] = find(father[x]);
d[x] += d[pre];
d[x] %= 3;
}
return father[x];
}
int judge(int k, int x, int y) {
int a = find(x);
int b = find(y);
if (a == b) {
if (k == 1 && d[x] != d[y])return 0;
if (k == 2 && d[x] == 0 && d[y] != 2)return 0;
if (k == 2 && d[x] == 1 && d[y] != 0)return 0;
if (k == 2 && d[x] == 2 && d[y] != 1)return 0;
return 1;
}
else {
father[a] = b;
if (k == 1)d[a] = (d[y] - d[x] + 3) % 3;
if (k == 2)d[a] = (d[y] - d[x] + 4) % 3;
return 1;
}
}
int main() {
int T;
cin >> n >> T;
for (int i = 0; i <= n; i++)father[i] = i;
while (T--) {
int k, a, b;
//cin >> k >> a >> b;
scanf("%d %d %d", &k, &a, &b);
if (a > n || b > n) {
sum++;
continue;
}
if (k == 2 && a == b) {
sum++;
continue;
}
int y = judge(k, a, b);
if (y == 0)sum++;
}
cout << sum << endl;
}