poj 1182(查并集)

本文解析了一个程序设计竞赛题目,通过使用并查集算法解决食物链关系问题,详细介绍了如何将三种生物类型映射到不同数组区间,以及如何通过合并操作来表达捕食和同类关系。

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

食物链

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 101460 Accepted: 30662

题目大意很简单理解

思路:用查并集,参考《挑战程序设计竞赛》思路,自己写了一份差不多的代码,代码中有注释

虽然这个题很老了,但个人感觉还是不错的

把三种类分成三组,但是这三组存在同一个数组里面分别是[1,n],[n+1,2*n],[2*n+1,3*n],

当比如1吃2,就是第一组的第一个和第二组的第二个合并,第二组的第一个和第三组的第二个合并,第三组的第一个和第一组的第二个合并,这就构成捕食关系,实质上都是1吃2.

当1和2同类时,就是同一组的第一个和第二个合并

最好用笔纸自己模拟一下,才好理解

代码:

#include <iostream>
#include <cstdio>

using namespace std;
const int N=50005;
int a[3*N];
void inti()
{
    for(int i=0;i<3*N;i++)
        a[i]=i;
}
int find_root(int n)
{
    return a[n]==n ? n : a[n]=find_root(a[n]);
}
void merge(int x,int y)
{
    int r1,r2;
    r1=find_root(x);
    r2=find_root(y);
    a[r1]=r2;
}
int same_root(int x,int y)
{
    return find_root(x)==find_root(y);
}
//上面的函数都是查并集的模板,无关紧要,重点思路在下面
int main()
{
    int n,k,d,x,y,ans;
    scanf("%d%d",&n,&k);
     ans=0;
     inti();//初始化
    while(k--)
    {
        scanf("%d%d%d",&d,&x,&y);
        if(x>n ||y>n||x<=0||y<=0)//不满足条件的
        {
            ans++;continue;
        }
        if(d==1)//第一种情况
        {
            if(same_root(x,y+n) || same_root(x,y+n*2))//两个函数分别说明是否构成捕食和被捕食,如果既不是捕食,也不是被捕食,那么就是同类
                ans++;
            else
            {
                merge(x , y);
                merge(x+n , y+n);
                merge(x+2*n , y+2*n);
            }
        }
        else//第二种情况
        {
            if(same_root(x,y) || same_root(x,y+2*n))//既不是同类也不是被捕食,那么就是捕食关系
                ans++;
            else
            {
                merge(x , y+n);
                merge(x+n , y+2*n);
                merge(x+2*n , y);
            }
        }
    }
     printf("%d\n",ans);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值