食物链
题意很简单,就是当时忘记x吃y那么y的猎物也能吃x了
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 5 * 1e4 +5;
//x+n为x的捕食者,x+2*n为x的猎物
int f[4 * maxn];
void init(int n)
{
for(int i = 1; i <= 4 * n; i++){
f[i] = i;
}
}
int Find(int root)
{
int son = root;
while(root != f[root]){
root = f[root];
}
//压缩路径
while(son != root){
int temp = f[son];
f[son] = root;
son = temp;
}
return root;
}
void add(int x,int y)
{
int a = Find(x);
int b = Find(y);
if(a != b){
f[a] = b;
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init(n);
int ans = 0;
while(m--){
int s,a,b;
scanf("%d%d%d",&s,&a,&b);
if(b <= 0||b > n||a <= 0||a > n){
ans++;
continue;
}
if(s == 1){
//如果a是b的捕食者或者a是b的猎物,那么肯定就是假话
if(Find(a) == Find(b + n)||Find(a) == Find(b + n * 2)){
ans++;
}
else{
add(a,b);
//同类的捕食者进行合并
add(a + n,b + n);
//同理,同类的猎物也要合并
add(a + 2 * n,b + 2 * n);
}
}
else{
//如果a是b同类,或者a是b的猎物或者a和b相等,就是假话
if(Find(a) == Find(b)||Find(a) == Find(b + 2 * n)||a == b){
ans++;
}
else{
//把 a 和 b的捕食者 合并
add(a,b + n);;
//把 a的猎物 和 b 合并
add(b,a + 2 * n);
//把 a的捕食者和 b的猎物合并 !!!
add(a + n,b + 2 * n);
}
}
}
printf("%d\n",ans);
return 0;
}