题目:
题目:
第一行是两个整数 N 和 K ,以一个空格分隔。
以下 K 行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中 D 表示说法的种类。
若 D=1,则表示 X 和 Y 是同类。
若 D=2,则表示 X 吃 Y 。
只有一个整数,表示假话的数目。
【样例说明】
对 7 句话的分析如下:
1 101 1 假话
2 1 2 真话
2 2 3 真话
2 3 3 假话
1 1 3 假话
2 3 1 真话
1 5 5 真话
分析:并查集升级版
因为一种生物和另一种的关系只有三种
代码
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
int dad[1000001];
int n,m;
int getdad(int x)
{
if(x==dad[x]) return x;
dad[x]=getdad(dad[x]);
return dad[x];
}
int read()
{
int k=0,f=1;
char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
while(c<='9'&&c>='0') {k=k*10+(c-'0'); c=getchar();}
return k*f;
}
void hb(int x,int y)
{
int a=getdad(x);
int b=getdad(y);
dad[a]=b;
}
int main()
{
//freopen("eat.in","r",stdin);
//freopen("eat.out","w",stdout);
n=read();
m=read();
int i,j,k,s,t;
for(i=1;i<=1000000;i++)
dad[i]=i;
int ans=0;
for(i=1;i<=m;i++)
{
k=read();
s=read();
t=read();
if(s>n||t>n){ans++; continue;}
if(s==t&&k==2) {ans++; continue;}
if(k==1)
{
if(getdad(s)==getdad(t+n)||getdad(s)==getdad(t+n+n)) {ans++;continue;}
hb(s,t); hb(s+n,t+n); hb(s+n+n,t+n+n);
}
if(k==2)
{
if(getdad(s)==getdad(t)||getdad(s)==getdad(t+n+n)) {ans++;continue;}
hb(s,t+n); hb(s+n,t+n+n); hb(s+n+n,t);
}
}
cout<<ans;
return 0;
}