POJ 1182 食物链(并查集拆点)

【题目链接】 http://poj.org/problem?id=1182

【题目大意】

  草原上有三种物种,分别为A,B,C

  A吃B,B吃C,C吃A。

  1 x y表示x和y是同类,2 x y表示x吃y

  问给出的信息有几条是和前面相违背的

【题解】

  之前这道题是用加权并查集做的,做的有些晕晕乎乎,现在换了种思路做就清晰很多了

  将每个点拆点,比如x拆为,x-A,x-B,x-C

  表示x属于A类,x属于B类,和x属于C类,

  如果y和x属于同类,那么合并x-A和y-A,x-B和y-B,x-C和y-C

  如果是x吃y的情况,那么合并x-A和y-B,x-B和y-C,x-C和y-A

  也就是说将x属于A这种类型的条件作为节点进行并查集运算

  就能很轻松地解决这种问题

【代码】

#include <cstdio>
const int N=50010*3;
int f[N],n,k,ans=0,op,x,y;
void init(int n){for(int i=0;i<=n;i++)f[i]=i;}
int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
bool Same(int x,int y){return sf(x)==sf(y);}
bool Union(int x,int y){f[sf(x)]=sf(y);}
int main(){
    scanf("%d%d",&n,&k);
    init(3*n);
    for(int i=1;i<=k;i++){
        scanf("%d%d%d",&op,&x,&y);
        if(--x<0||x>=n||--y<0||y>=n){ans++;continue;}
        if(op==1){
            if(Same(x,y+n)||Same(x,y+2*n))ans++;
            else{Union(x,y);Union(x+n,y+n);Union(x+2*n,y+2*n);}
        }else{
            if(Same(x,y)||Same(x,y+2*n))ans++;
            else{Union(x,y+n);Union(x+n,y+2*n);Union(x+2*n,y);}
        }
    }printf("%d\n",ans);
    return 0;
}

  

时间: 2024-10-03 06:43:45

POJ 1182 食物链(并查集拆点)的相关文章

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

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

poj 1182 食物链 并查集

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 (关系并查集) 食物链

题目传送门:http://poj.org/problem?id=1182 这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃: 所以可以用0,1,2三个数字代表三种情况,在使用并查集的时候再多加一个关系数组,初始时全部赋值为0 然后就是在进行并查集的每一步时加入关系的改变, 如果祖先节点相同,说明两者之间的关系已经出现,是已知的,判断两者关系之和与给的d-1是否相同 祖先节点不同,说明在此之前两者的关系还未知,就赋予关系 噢 对了 poj 上的这题要单组输入,多组会wa c

Poj(1182),种类并查集

题目链接:http://poj.org/problem?id=1182 再次熟练种类并查集,又积累点经验,和技巧,rank 0 2 1 先计算father[x] ,再更新rank[x]; #include <stdio.h> int father[50010]; int rank[50010]; int Find_Set (int x) { int tmp; if(x!=father[x]) { tmp = father[x]; father[x] = Find_Set(father[x]);

POJ 1182(食物链-另类做法【拆点】)[template:并查集]

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

食物链 POJ 1182(并查集)

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 (扩展并查集)

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

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当

又见关系并查集 以POJ 1182 食物链为例

简单的关系并查集一般很容易根据给出的关系搞出一个有向的环,那么两者之间的关系就变成了两者之间的距离. 对于此题: 若u,v不在一个集合内,则显然此条语句会合法(暂且忽略后两条,下同). 那么将fu 变为 fv的儿子时需加一条权值为 w 的边,w 满足(w + ru)%3 = (rv+ (D == 1? 0 : 1))%3(ru,rv分别为u,v与fv的关系,即距离). 之所以在D == 2时加 1,是因为u吃v表明着u到fv的距离比v到fv的距离大1. 同理,D == 1时,表明两者到fv的距离