并查集详解
https://blog.csdn.net/sjystone/article/details/115406797
食物链 https://www.acwing.com/problem/content/242/
每次合并集合a,b的时候
用d[pa]维护a和b的关系
若a,b在一个集合
若(d[a] - d[b]) % 3 = 1 -> a吃b
若(d[a] - d[b]) % 3 = 0 -> ab同类
若a,b不在同一集合
若a吃b,则令d[pa] = d[b] - d[a] + 1 -> 以满足(d[a] + d[pa] - d[b]) % 3 = 1
若ab同类,则令d[pa] = d[b] - d[a] -> 以满足(d[a] + d[pa] - d[b]) % 3 = 0;
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int p[N], d[N], n, m, res;
int find(int x)
{
if ( x != p[x] )
{
int root = find(p[x]);
d[x] += d[p[x]];
p[x]= root;
}
return p[x];
}
int main()
{
cin >> n >> m;
for ( int i = 1; i <= n; i ++ ) p[i] = i;
while ( m -- )
{
int op, a, b;
cin >> op >> a >> b;
if ( a > n || b > n ) res ++;
else
{
int pa = find(a), pb = find(b);
if ( op == 1 )
{
if ( pa == pb && (d[a] - d[b]) % 3 ) res ++;
else if ( pa != pb )
{
p[pa] = pb;
d[pa] = d[b] - d[a];
}
}
else
{
if ( pa == pb && (d[a] - d[b] - 1) % 3 ) res ++;
else if ( pa != pb )
{
p[pa] = pb;
d[pa] = d[b] - d[a] + 1;
}
}
}
}
cout << res;
return 0;
}