【洛谷】 NOI 2024 食物链

本文介绍了一种使用并查集数据结构来解决一类关于动物间关系的问题的方法。问题包含三种动物及其相互间的猎物、天敌和同类关系。通过维护三个并查集来跟踪这些关系的变化,可以有效地区分真实陈述与虚假陈述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很好的并查集问题。

 

题目不是很难理解 : 有3类动物,对于每一类动物分别存在它的猎物、天敌、与同类。不难看出我们需要开三个并查集去存储每一只动物的猎物、天敌、与同类。

 

处理每一次遇到的话:

首先判断它是关于同类的叙述还是天敌的叙述,对于这次所涉及的动物X与Y:

 

1、同类:首先判断Y存不存在于X天敌或者是猎物的并查集中,如果两者都不存在,那么一定是同类了,说明当前的声明的是真话,并进行将Y合并到X同类的并查集中、X合并到Y同类的并查集中的操作;否则当前的声明的是假话,ans++,并跳过所有操作。

 

2、Y是X的猎物:首先判断Y存不存在于X天敌或者同类的并查集中,如果两者都不在的话,Y一定是X的猎物了,说明当前的声明是真话,并进行将Y合并到X猎物的并查集中、X合并到Y天敌的并查集中的操作;否则说明当前的声明是假话,ans++,并跳过所有操作。

 

直观感受一下:

 

其实只用开一个并查集,这个并查集不同的区间代表不同的类别(猎物、天敌、与同类),如上图。

 

OK & AC。

 

代码:


#include <bits/stdc++.h>

const  int  N = 500000 + 5 ;

int  f [ N ] , n , k , ans , ok , Y , X ; 

int  find ( int  x ) {
    return  f [ x ] == x ? x : ( find ( f [ x ] ) ) ;
}

int  main ( ) {
    scanf ( "%d%d" , & n , & k ) ;
    for ( int  i = 1 ; i <= 3 * n ; i ++ )  f [ i ] = i ;  
    for ( int  i = 1 ; i <= k ; i ++ ) {
        scanf ( "%d%d%d" , & ok , & X , & Y ) ;
        if ( X > n  ||  Y > n ) {  ans ++ ; continue ;  }
        if ( ok == 1 ) {
            if ( find ( X + n ) == find ( Y )  ||  find ( X + 2 * n ) == find ( Y ) )
                ans ++ ;
            else {
                f [ find ( X ) ] = find ( Y ) ;
                f [ find ( X + n ) ] = find ( Y + n ) ;
                f [ find ( X + 2 * n ) ] = find ( Y + 2 * n ) ;
            }
        }
        else {
            if ( X == Y ) {  ans ++ ; continue ;  }
            if ( find ( X ) == find ( Y )  ||  find ( X + 2 * n ) == find ( Y ) )
                ans ++ ;
            else {
                f [ find ( X + 2 * n ) ] = find ( Y + n ) ;
                f [ find ( X + n ) ] = find ( Y ) ;
                f [ find ( X ) ] = find ( Y + 2 * n ) ;
            }
        }
    }
    printf ( "%d" , ans ) ; 
    return  0 ;
}

引用食物链问题的。这段代码使用了并查集算法来判断两个动物是否在同一个食物链上,并计算满足要求的食物链的数量。 食物链是什么? 回答: [NOI2001 食物链是一个关于动物之间食物关系的问题。根据给出的描述,动物王国中有三类动物A, B, C,它们之间形成了一个环形的食物链,其中A吃B,B吃C,C吃A。问题要求我们计算满足要求的食物链的数量。这个问题可以使用并查集算法进行解决,通过判断两个动物是否在同一个食物链上来计算满足要求的食物链的数量。 [2<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [[NOI2001] 食物链](https://blog.youkuaiyun.com/qq_43219250/article/details/126453235)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [[NOI2001]食物链](https://blog.youkuaiyun.com/aoniebu42564/article/details/102140448)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值