0%

食物链

题目链接:https://ac.nowcoder.com/acm/problem/16884

题意:有N只动物,这些动物属于A、B、C的其中一种;已知A吃B、B吃C、C吃A。接着有K条信息,第一种:x和y是同类;第二种:x吃y。 问有多少条信息是假的?

思路:对于每只动物i创建3个元素i-A,i-B,i-C,并用3*N个元素建立并查集。
维护并查集:
第一种:x和y同类: unite(x-A,y-A),unite(x-B,y-B),unite(x-c,y-c);
第二种:x吃y: unite(x-A,y-B),unite(x-B,y-C),unite(x-C,y-A);
如果出现第i条信息发生冲突 则说明是假话,ans++;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=3e5+5;
int par[MAXN];
int height[MAXN];
int N,K;
void init(int n)
{
for(int i=1;i<=n;i++)
{
par[i]=i;
height[i]=1;
}
}


int Find(int x)
{
if(par[x]==x) return x;
else return par[x]=Find(par[x]);
}

void unite(int x,int y)
{
x=Find(x);
y=Find(y);
if(x==y) return;
if(height[x]<height[y])
{
par[x]=y;
}
else {
par[y]=x;
if(height[x]==height[y]) height[x]++;
}
}

bool same(int x,int y)
{
return Find(x)==Find(y);
}


void solve()
{
init(3*N);
int ans=0;
int t,x,y;
for(int i=1;i<=K;i++)
{
scanf("%d%d%d",&t,&x,&y);
if(x<=0||N<x||y<=0||N<y) {ans++;continue;}
if(t==1)
{
if(same(x,y+N)||same(x,y+2*N)) ans++;
else
{
unite(x,y);
unite(x+N,y+N);
unite(x+2*N,y+2*N);
}
}
else
{
if(same(x,y)||same(x,y+2*N)) ans++;
else
{
unite(x,y+N);
unite(x+N,y+2*N);
unite(x+2*N,y);
}
}
}
printf("%d\n",ans);
}


int main(){
scanf("%d%d",&N,&K);
solve();
return 0;
}
-------------本文结束感谢您的阅读-------------