Luogu P2024 食物链

Posted czyty114

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P2024 食物链相关的知识,希望对你有一定的参考价值。

(Description)https://www.luogu.com.cn/problem/P2024

一道带权并查集的题

这道题很重要的一点就是:
(3)种不同的动物(A,B,C)。且(A)(B)(B)(C)(C)(A)
由此我们可以得到:对于一个动物,有它的同类、天敌、猎物。
按照我们并查集的思想:只要算出每个点到这个集合根节点的关系,就可以间接地算出每两两个点之间的关系了
(d_x)表示(x)这个点到根节点的距离((mod;;3))
则:当(d_x=0)时,表示:根节点是(x)的同类
(d_x=1)时,表示:根节点是(x)的猎物
(d_x=2)时,表示:根节点是(x)的天敌
这里模(3)是因为:我们做的事情是在长度为(3)的环上的关系传递

那假设现在有两个动物(x,y)在同一个集合内,如何判断它们之间的关系?
(d_x = d_y)时,显然(x)(y)是同类
如何判断(x)(y)?根据前面的(0,1,2)的关系。打表即可发现:
(x)的同类的猎物等价于(x)的猎物 (=> d_x=0,d_y=2)
(x)的猎物的同类等价于(x)的猎物 (=> d_x=1,d_y=0)
(x)的天敌的天敌等价于(x)的猎物 (=> d_x=2,d_y=1)
则当(d_x=d_y+1)时,满足这个性质。
则当(d_x+1=d_y)时,自然就是(y)(x)

因此我们在合并两个集合的时候遵循上面的原则:
(x,y)的祖先是(p,q)。则我们把(p)接到(q)上,(d_p=?)
(x,y)是同类时,我们要使:

[d_x=d_y;(mod;;3) ]

则:

[d_x+d_p=d_y;(mod;;3) ]

[d_p=d_y-d_x;(mod;;3) ]

[d_p=(d_y-d_x+3)\% 3 ]

同理,当(x)(y)时,我们要使:

[d_x=d_y+1;(mod;;3) ]

则:

[d_x+d_p=d_y+1;(mod;;3) ]

[d_p=d_y-d_x+1;(mod;;3) ]

[d_p=(d_y-d_x+4)\%3 ]

(Code:)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=50010;
int n,K,f[N],d[N],res;
int find(int x)
{
    if(f[x]!=x)
    {
        int root=find(f[x]);
        d[x]=(d[x]+d[f[x]])%3;
        f[x]=root;
    }
    return f[x];
}
int main()
{
    scanf("%d%d",&n,&K);
    for(int i=1;i<=n;i++)f[i]=i;
    while(K--)
    {
        int opt,x,y;
        scanf("%d%d%d",&opt,&x,&y);
        if(x>n||y>n)
        {
            res++;
            continue;
        }
        if(opt==1)
        {
            int p=find(x),q=find(y);
            if(p==q)
            {
                if(d[x]!=d[y])
                {
                    res++;
                    continue;
                }
            }
            else 
            {
                f[p]=q;
                d[p]=(3-d[x]+d[y])%3;
            }
        }
        else
        {
            int p=find(x),q=find(y);
            if(p==q)
            {
                if(d[x]==d[y]||d[x]!=(d[y]+1)%3)
                {
                    res++;
                    continue;   
                }
            }
            else
            {
                f[p]=q;
                d[p]=(4-d[x]+d[y])%3;
            }
        }
    }
    printf("%d",res);
    return 0;
}

以上是关于Luogu P2024 食物链的主要内容,如果未能解决你的问题,请参考以下文章

P2024 食物链

洛谷P2024 食物链

P2024 [NOI2001] 食物链(并查集)

P2024 食物链

做题记录:P2024 食物链(洛谷)

P2024 食物链