题目大意

动物王国中有三类动物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),输出假话的总数。

题目分析

由于给出X和Y的相对关系,并不能确定X和Y分别是哪种动物,因此没法将动物i属于A、B、C中的哪一类作为一个集合。但是,题目是典型的集合操作,判断两个元素是否符合某种关系,因此仍然考虑使用并查集来解决。
    使用并查集这种结构时候,需要维护相关的数据信息。考虑每两个动物只要能够确定相互关系,则将他们加入一个集合,对于集合中的每个动物,我们维持
该动物和该集合的根节点动物的相对关系。在每次获得两个动物X和Y的相对关系的时候,对于之前已经知道的那些和X或Y相关的动物的关系,只需要知道这些动
物和该共同集合的根节点动物的相对关系,则可以确定他们之间的相对关系。
    在每次得到X和Y之间的关系rel时,先获得他们的根节点,如果根节点p相同,则可以通过X和p的关系,Y和p的关系,确定X和Y在之前就可以确
定的关系rel_1。将rel_1和本次输入的X和Y之间的关系rel进行对比,如果不同,则说明出错;如果根节点不同,分别为px,
py,则将px和py合并,然后根据X和px的关系,X和Y的关系,y和py的关系,得到px和py的关系。

关于带权并查集

带权并查集和普通并查集最大的区别在于带权并查集合并的是可以推算关系的点的集合(可以通过集合中的一个已知值推算这个集合中其他元素的值)。而一般并查集合并的意图在于这个元素属于这个集合。带权并查集相当于把“属于”的定义拓展了一下,拓展为有关系的集合。

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX_ANIMAL_NUM 50010
int gPar[MAX_ANIMAL_NUM]; //集合的根节点
int gRel[MAX_ANIMAL_NUM]; //节点和所属集合的根节点之间的关系 //gRel[i] == 0, i 和它的最老祖先是同类动物
//gRel[i] == 1, i 吃它的最老祖先
//gRel[i] == 2, i 的最老祖先吃它
void Init(int n){
for (int i = 1; i <= n; i++){
gPar[i] = i;
gRel[i] = 0;
}
} //获得集合的根节点,同时维护信息,主要是更新 节点到跟节点的关系数组 gRel[x]
int GetPar(int c){
if (c != gPar[c]){
int p = gPar[c]; //c还没被进行路径压缩前,节点c所属集合的根节点 p
gPar[c] = GetPar(gPar[c]); //进行路径压缩,路径压缩之后,递归函数返回时,p已经设置了根节点,同时也设置了p和总集合的根节点的关系
gRel[c] = (gRel[c] + gRel[p]) % 3; //根据c和p的关系,以及p和总集合的根节点的关系,设置c和总集合的根节点的关系
}
return gPar[c];
} int main(){
int N, K;
scanf("%d %d", &N, &K);
int rel, x, y;
int error_count = 0;
Init(N);
for (int i = 0; i < K; i++){
scanf("%d %d %d", &rel, &x, &y);
if (x > N || y > N){
error_count++;
continue;
}
rel--;
int p1 = GetPar(x), p2 = GetPar(y);
if (p1 == p2){
if ((gRel[x] + 3 - gRel[y]) % 3 != rel){ //关系不一致
error_count++;
}
}
else{ //对集合进行合并,同时需要注意,根据 x-->p1, x->y, y->p2的关系,得到 p1->p2的关系
gPar[p1] = p2;
gRel[p1] = (3 - gRel[x] + rel + gRel[y]) % 3;
}
}
printf("%d\n", error_count);
return 0;
}

poj_1182 并查集的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  2. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  3. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  4. bzoj1854--并查集

    这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...

  5. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  6. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  7. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  8. Codeforces 731C Socks 并查集

    题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...

  9. “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)

    题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...

随机推荐

  1. busybox内置ftp服务器用法

    参考:http://blog.chinaunix.net/uid-20564848-id-74041.html 最新的busybox已集成ftp服务器层需ftpd,使用方法如下: 方法一:# tcps ...

  2. find 下参数的关系默认是and 一个参数多个选项可以用 -or

    [root@ob2 mytmp]# find -type f -name "*.html" -or -name "*.txt"./02.html./aa.htm ...

  3. Struts2- 设置默认拦截器

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...

  4. 关于添加图片到svg中,rails下使用js, 用parseFloat来调整force.on时的位置

    注意在代码中用/表示路径...windows中file才是\ 1.<image xlink:href=<%= asset_path 'vnet/virtual_switch.png' %& ...

  5. 12款优秀 jQuery Ajax 分页插件和教程

    12款优秀 jQuery Ajax 分页插件和教程 在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 W ...

  6. Firefox 在LR录制过程中添加例外的问题解决方法

    用lr调火狐打开网页  会报证书安全问题 证书安全提示目的是告诉你这个服务器使用的证书可能不安全,要不要信任,你自己决定,不信任就不能访问.为什么会报证书安全,因为浏览器没添加该证书.或者由于性能工具 ...

  7. C语言写的trim()函数

    C语言的标准库中缺少对字符串进行操作的trim()函数,使用起来有些不便,可以使用利用 strlen 和 isspace 函数以及指针来自己写一个. 1.strlen 函数 原型:extern int ...

  8. 《FPGA全程进阶---实战演练》第二章之PCB layout注意事项以及投板几点说明

           上一篇博客讲述了各个部分的原理图,那么根据原理图画出PCB,其实PCB是一门很大的学问,想要掌握谈何容易.就笔者在画PCB时的一些注意事项做一些说明.        1.电源部分的电源线 ...

  9. taskAffinity属性

    Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系.我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Tas ...

  10. UVA 1371 - Period(DP)

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=4117&mo ...