多学习。

【并查集】AcWing240. 食物链(并查集维护额外信息)

AcWing240. 食物链


题解

(2->1代表1吃2)
轻易可知,该食物链成一个环,只要得知该环中两条边,即可推出第三条边
将所有点存储在一个集合中,集合的边表示结点之间的关系,利用点到根节点的距离判断种类,故我们需要额外维护一个保存到父节点距离的数组。

路径压缩:还是将父节点直接改为根节点,距离从到父节点距离改为到根节点的距离。

数学中的模和c++的模不同,所以判断要用(d[x] - d[y])这样的方式 (余数为0就不会出现冲突)

比如说: -98 % 3 在数学中的模没有负数 即为 -98 % 3 = -2 (-2 + 3)% 3 = 1

c++中只有-98 % 3 = -2

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 50010;

int p[N], d[N];

int find(int x)
{
    if(p[x] != x)
    {
        int t = p[x];
        p[x] = find(p[x]);
        d[x] += d[t];
    }
    return p[x];
}

int main()
{
    int n, m, t, x, y;
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i <= n; ++i) p[i] = i;
    
    int res = 0;
    while (m -- )
    {
        scanf("%d%d%d", &t, &x, &y);
        if(x > n || y > n) res ++ ;
        else
        {
            int px = find(x), py = find(y);
            if(t == 1)
            {
                if(px == py && (d[x] - d[y]) % 3) res ++ ; //在同一个集合中余数不同为假话
                else if(px != py)//不在一个集合中,即两点没有确立关系,默认为真,开始确立关系
                {
                    p[px] = py;
                    d[px] = d[y] - d[x];
                }
            }
            else 
            {
                if(px == py && (d[x] - d[y] - 1) % 3 ) res ++ ;
                else if(px != py)
                {
                    p[px] = py;
                    d[px] = d[y] - d[x] + 1;
                }
            }
        }
    }
    printf("%d\n", res);
    return 0;
}
posted @   czyaaa  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示