#include <iostream>
using namespace std;
const int N = 5e5+10;
int p[N],d[N];
int Find(int x)
{
if (x != p[x])
{
int t = Find(p[x]);
d[x] += d[p[x]];//到父结点的距离
p[x] = t;
}
return p[x];
}
int main()
{
int n, k;//n个动物,k句话
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
p[i] = i;//初始化并查集
}
int D, x, y;
int cnt = 0;//假话条数
while (k--)
{
cin >> D >> x >> y;
if ( x > n || y > n)
{
cnt++;
continue;
}
int px = Find(x), py = Find(y);
if (1 == D)//表明X,Y是同类
{
if (px == py && (d[x] - d[y])%3)//x,y在同一集合中,x,y到根结点的距离模3不同余,则不是同类
{
cnt++;
continue;
}
else if (px != py)//不在同一个集合中,合并
{
p[px] = py;
d[px] = d[y] - d[x];
}
}
else//x吃y
{
if (px == py && (d[x] - d[y] - 1) % 3)
{
cnt++;
}
else if (px != py)
{
p[px] = py;
d[px] = d[y] - d[x]+ 1;
}
}
}
cout << cnt << endl;
return 0;
}
//其中 int t = Find(p[x]);
d[x] += d[p[x]];//到父结点的距离
p[x] = t;
不能修改成 d[x] += d[p[x]];//到父结点的距离
p[x] = Find(p[x]);
因为这样一来只会先求出d[x]到d[p[x]]的距离,而没有累加至根结点的距离,d[p[x]]是指向父节点的距离,必须先用find递归调用至根结点,再路径压缩后能得到d[x]到根结点的距离。