POJ1182食物链(并查集)

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句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。

Input

第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output

3

思路:判断x和y是否是同一种类用裸的并查集就能搞定,关键是如何判断x吃y;不妨把0~N-1看作集合A,N~2*N-1看作集合B,N~3*N-1看作集合C(集合A,B,C谁在前不重要,重要的是A吃B,B吃C,C吃A的对应关系)用T[max_k]数组来存放是第几种关系(同一类还是捕食);

那么怎么判断它们是不是同一类呢?若x和y是同一类,则x和y或同在A集合中或同在B集合中或同在C集合中,即same(x,y)||same(x+n,y+n)||same(x+n*2,y+n*2);

同理判断捕食关系:same(x,y+n)||same(x+n,y+n*2)||same(x+n*2,y);

注:代码是从反面判断它们的关系

#include <cstdio>

using namespace std;

#define max_k 100010
#define max_s 150010

int n,k;
int T[max_k],X[max_k],Y[max_k];
int par[max_s];

void init(int s)
{
    for(int i=0;i<s;i++)
    {
        par[i]=i;
    }
}

int find(int x)
{
    if(par[x]==x)
        return x;
    else
    {
        return par[x]=find(par[x]);
    }
}

bool same(int a,int b)
{
    return find(a)==find(b);
}

void unit(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    par[fx]=fy;
}

void solve()
{
    init(n*3);
    int ans=0;
    for(int i=0;i<k;i++)
    {
        int t=T[i];
        int x=X[i]-1,y=Y[i]-1;

if(x<0||x>=n||y<0||y>=n)
        {
            ans++;
            continue;
        }

if(t==1)
        {
            if(same(x,y+n)||same(x,y+n*2))
                ans++;
            else
            {
                unit(x,y);
                unit(x+n,y+n);
                unit(x+n*2,y+n*2);
            }
        }
        else
        {
            if(same(x,y)||same(x,y+n*2))
                ans++;
            else
            {
                unit(x,y+n);
                unit(x+n,y+n*2);
                unit(x+n*2,y);
            }
        }
    }
    printf("%d\n",ans);
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<k;i++)
    {
        scanf("%d%d%d",&T[i],&X[i],&Y[i]);
    }
    solve();
    return 0;
}

				
时间: 2024-12-14 03:42:38

POJ1182食物链(并查集)的相关文章

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句话,这

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是同

POJ1182 食物链 并查集 好题

食物链 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句话有的是真的,有的是假的.当一句话满足下

编程算法 - 食物链 并查集 代码(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,

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

[acwing 240] 食物链 [并查集] 传送门 题意 ABC三种动物,食物链构成一个环形,,给出M个关于彼此关系的描述,判断有多少个假话. 1 X Y表示同类 2 X Y表示X吃Y 思路 本题是并查集的一种比较新颖的用法,并查集一般用来维护集合,但是在这里主要是使用路径压缩来维护点和根之间的距离. 动物之间有三种关系(同类,捕食,被捕食),并且食物链构成环,那么可以使用和根之间的距离模3来区分三种关系,这里并不严格划分集合,主要是借助了并查集中的路径压缩. 红色的线是不存在的,只是为了方便

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编号.每个动物

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