题目
题意:
给出n只动物和k句话,判断这k句话里有几句假话。
思路:
题目中告诉了我们假话的几种情况:
• 当前的话与前面的某些真的话冲突,就是假话
• 当前的话中 X 或 Y 比 N 大,就是假话
• 当前的话表示 X 吃 X,就是假话
我们可以用x表示同类,x+n表示猎物,x+2n表示天敌,然后我们在读入的时候判断后两种情况,第一种另外判断。
代码:
#include<cstdio>
int n,k,x,y,z,ans,father[150050];
int find(int a)
{
if (father[a]!=a) father[a]=find(father[a]);
return father[a];
}
void unionn(int f1,int f2) {int a=find(f1),b=find(f2);father[a]=b;}
int main()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=3*n;i++) father[i]=i;
for (int i=1;i<=k;i++)
{
scanf("%d%d%d",&z,&x,&y);
if (x>n||y>n) {ans++;continue;}//第二种情况
if (z==1)
{
if (find(x+n)==find(y)||find(x+2*n)==find(y)) {ans++;continue;}//y是x的猎物或y是x的天敌就是假话
unionn(x,y);unionn(x+n,y+n);unionn(x+2*n,y+2*n);//把x和y合并,x的猎物和y的猎物合并,x的天敌和y的天敌合
} //并
else
{
if (x==y) {ans++;continue;}//第三种情况
if (find(x)==find(y)||find(x+2*n)==find(y)) {ans++;continue;}//如果x是y的同类或天敌就是假话
unionn(x,y+2*n);unionn(x+n,y);unionn(x+2*n,y+n);//否则我们把x和y的天敌合并,x的猎物和y合并,x的天敌和y
} //的猎物合并
}
printf("%d",ans);
}