# [acwing 240] 食物链 [并查集]

[acwing 240] 食物链 [并查集]

传送门

题意

ABC三种动物,食物链构成一个环形,,给出M个关于彼此关系的描述,判断有多少个假话。

  • 1 X Y表示同类
  • 2 X Y表示X吃Y

思路

本题是并查集的一种比较新颖的用法,并查集一般用来维护集合,但是在这里主要是使用路径压缩来维护点和根之间的距离。

动物之间有三种关系(同类,捕食,被捕食),并且食物链构成环,那么可以使用和根之间的距离模3来区分三种关系,这里并不严格划分集合,主要是借助了并查集中的路径压缩。

红色的线是不存在的,只是为了方便理解。图中的关系是:

  • 2吃1 ,3吃2,4吃3,6吃4,5吃1。
  • 其中3被1和4吃,那么1和4是同类(因为食物链是环形的,吃同一种动物的就是同类),1和4到1的距离模3都是0。
  • 2,5,6是同类,模3都是1,都是1的捕食者

使用d[]维护节点x到父节点的距离,路径压缩时只要更新d[]的值

Code:

#include <iostream>
using namespace std;
const int maxn=5e4+10;
int n,m;
int p[maxn],d[maxn];
inline int find(int x){
    if(p[x]==x)return x;

    int t=find(p[x]);
    d[x]+=d[p[x]];//x节点到父节点p[x]的距离加上父节点到父父节点的距离,递归可得到根节点的距离
    p[x]=t;//最终父节点更新成根节点
    return p[x];
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;++i)p[i]=i;

    int ans=0;
    for(int i=0,r,x,y;i<m;++i){
        scanf("%d %d %d",&r,&x,&y);
        if(x>n||y>n)ans++;
        else {
            int px=find(x),py=find(y);
            if(r==1){
                if(px==py&&(d[x]-d[y])%3)ans++;//同一颗树上,同类的动物模3同余
                else if(px!=py){//不在一个集合,无法判断是错误,那么是正确,那么构造同类关系
                    p[px]=py;
                    //合并的时候d[px]+d[x]和d[y]模3同余,即(d[px]+d[x]-d[y])%3==0
                    //可以认为d[px]=d[y]-d[x]。其他关系同理
                    d[px]=d[y]-d[x];
                }
            }
            else {//x吃y
                if(px==py&&(d[x]-d[y]-1)%3)ans++;
                else if(px!=py){
                    p[px]=py;
                    d[px]=d[y]+1-d[x];
                }
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/sstealer/p/12234102.html

时间: 2024-10-07 02:59:54

# [acwing 240] 食物链 [并查集]的相关文章

编程算法 - 食物链 并查集 代码(C)

食物链 并查集 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种. 已知A吃B, B吃C, C吃A. 按顺序给出两种信息K条. 第一种: x和y属于同一类. 另外一种: x吃y.  信息之间可能会出错和矛盾, 求不对的信息数. 比如: 有N=10仅仅动物, 给定K=7条信息. (1) 1: x=101, y=1; 出错:没有101的动物. (2) 2: x=1,

POJ1182 食物链 (并查集)*新方法

本文出自:http://blog.csdn.net/svitter 题意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这

ACWing 240. 食物链 带权并查集

题目: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形. A吃B, B吃C,C吃A. 现有N个动物,以1-N编号. 每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是”1 X Y”,表示X和Y是同类. 第二种说法是”2 X Y”,表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的. 当一句话满足下列三条之一时,这句话就是假话,否则就是真话. 1

POJ 1182 (经典食物链 /并查集扩展)

(參考他人资料) 向量偏移--由"食物链"引发的总结 http://poj.org/problem?id=1182这道食物链题目是并查集的变型.非常久曾经做的一次是水过的,这次细致地研究了这"食物链",无非就是运用向量偏移.从曾经节点与节点转化成向量与向量的关系.我们能够把矛盾的产生得益于向量偏移时的结果. 直接引出向量偏移的运用. 以下是POJ一位大牛这样理解的,本人稍有改动. 对于集合里的随意两个元素a,b而言,它们之间必然存在着某种联系,由于并查集中的元素

POJ 1182 食物链 [并查集 带权并查集 开拓思路]

传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1182 Appoint description:  System Crawler  (2015-01-27) Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物

POJ1182 食物链 [并查集]

很好的题,分析与题解转自: http://blog.csdn.net/tiantangrenjian/article/details/7085575 http://blog.csdn.net/c0de4fun/article/details/7318642/ 这题不知道为啥写成多组用例不能过,,,oj的一个bug吧~ 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26553   Accepted: 7718 De

poj1182食物链-并查集

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 83337   Accepted: 24925 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同

NOI 2001 食物链 /// 并查集 oj22035

Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1~N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之

poj 1182 食物链 并查集好题

挑战程序设计上有解答的并查集好题.把事件作为元素进行合并,举例:若输入1 2 3,意思就是把2,3归为同一类,至于归于哪一类并不需要去讨论,则把2属于A,3属于A这两件事件归为一类;2属于B,3属于B这两件事归为一类;2属于C,3属于C这两件事归为一类:若输入 2 2 3,由于A吃B,B吃C,C吃A,就把2属于A,3属于B这两件事情归为一类:以此类推.当检测到当前情况与之前正确的情况不符合,则错误的情况数加1. #include <iostream> #include <cstdio&g