洛谷P2024 食物链

好,经典扩展域并查集(冰茶几)。

因为有三个动物形成环(这不生物),所以并查集开3倍。

x - y 表示同类,x - (y + n) 表示 y 吃 x

然后瞎搞搞即可。

思考:如果不是环,就是个A <- B <- C的食物链呢?如果还有A吃C呢?

据说是bitset

 1 #include <cstdio>
 2 
 3 const int N = 50010;
 4 
 5 int fa[N * 3], n;
 6 
 7 int find(int x) {
 8     if(x == fa[x]) {
 9         return x;
10     }
11     return fa[x] = find(fa[x]);
12 }
13 
14 inline void merge(int x, int y) {
15     fa[find(x)] = find(y);
16     return;
17 }
18 
19 inline bool check(int f, int x, int y) {
20     if(f == 1) {
21         return find(x) != find(y + n) && find(x) != find(y + n + n);
22     }
23     return find(x) != find(y) && find(y + n) != find(x);
24 }
25 
26 inline void add(int f, int x, int y) {
27     if(f == 1) {
28         if(find(x) == find(y)) {
29             return;
30         }
31         merge(x, y);
32         merge(x + n, y + n);
33         merge(x + n + n, y + n + n);
34     }
35     else {
36         if(find(x + n) == find(y)) {
37             return;
38         }
39         merge(x + n, y);
40         merge(x + n + n, y + n);
41         merge(x, y + n + n);
42     }
43     return;
44 }
45 
46 int main() {
47     int m;
48     scanf("%d%d", &n, &m);
49     for(int i = 1; i <= n * 3; i++) {
50         fa[i] = i;
51     }
52     int f, x, y, ans = 0;
53     for(int i = 1; i <= m; i++) {
54         scanf("%d%d%d", &f, &x, &y);
55         if(x > n || y > n) {
56             ans++;
57             continue;
58         }
59         else if(f == 2 && x == y) {
60             ans++;
61             continue;
62         }
63         if(check(f, x, y)) {
64             add(f, x, y);
65         }
66         else {
67             ans++;
68         }
69     }
70     printf("%d", ans);
71     return 0;
72 }
AC代码

 

转载于:https://www.cnblogs.com/huyufeifei/p/9623423.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值