You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.3 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
const int M = 3;
//带权并查集
/**
*
*
*
*
*
*/
int n, m;
int p[N]; //父亲是谁
int d[N]; //i结点到父结点的距离
int res; //假话的个数
/**
* pi
* di
* d[x]=1 : x
* d[x]=2 : x
* d[x]=0 : x
* @param x
* @return
*/
int find(int x) {
if (p[x] != x) {
int t = find(p[x]);
d[x] = (d[p[x]] + d[x]) % M;
p[x] = t;
}
return p[x];
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) p[i] = i; //并查集初始化
//m个条件
while (m--) {
int t, x, y;
cin >> t >> x >> y;
//如果出现x,y的序号大于最大号那么肯定是有问题是假话
if (x > n || y > n) {
res++;
continue;
}
//找出祖先
int px = find(x), py = find(y);
//t==1,同类
if (t == 1) {
//同一个家族而且距离值差模3不等于0表示不是同类,结果值++
if (px == py && (d[x] - d[y] + M) % M) res++;
//如果不是同一个家族,需要合并并查集
if (px != py) {
p[px] = py;//将px认py为祖先
d[px] = (d[y] - d[x] + M) % M; //修改路径长度
}
}
//t==2,表示X吃Y
if (t == 2) {
//同一个家族,但距离并不是1,那就是错误答案
if (px == py && (d[x] - d[y] + M) % M != 1) res++;
//不在同一个家族内,描述刚录入进来的信息,肯定是真话,记录这个信息
if (px != py) {
p[px] = py;//将px认py为祖先
d[px] = (d[y] + 1 - d[x] + M) % M;//修改路径长度
}
}
}
//输出大吉
printf("%d\n", res);
return 0;
}