poj_1182 并查集
题目大意
动物王国中有三类动物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 并查集的更多相关文章
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
- “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)
题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...
随机推荐
- OFFLINE
2013年9月22日 20:47:42 OFFLINE 今天没有网络,或许,只有没有网络才去做一些更加有意义的事情.人就是这么贱,不是么.或许已经有点强迫症的味道的了. 中午吃完饭有2个小时的休息时间 ...
- Android 自定义Adapter实现多视图Item的ListView
自定义Adapter实现多视图Item的ListView http://www.devdiv.com/adapter_item_listview-blog-20-7539.html 1.原理分析 Ad ...
- linux下使用yum安装telnet
参考文章: http://futeng.iteye.com/blog/2039490?utm_source=tuicool&utm_medium=referral
- Spring下获取项目根路径--good
Spring 在 org.springframework.web.util 包中提供了几个特殊用途的 Servlet 监听器,正确地使用它们可以完成一些特定需求的功能.比如某些第三方工具支持通过 ${ ...
- tomcat http协议与ajp协议
AJP13是定向包协议.因为性能原因,使用二进制格式来传输可读性文本.WEB服务器通过 TCP连接和SERVLET容器连接.为了减少进程生成 socket的花费,WEB服务器和SERVLET容器之间尝 ...
- 另外一款超棒的响应式布局jQuery插件 – Freetile.js
在线演示 我们曾经介绍过俩款知名的响应式布局插:isotope和masonary,今天我们这里再介绍一款相当不错的响应式布局插件 – Freetile.js,使用它同样可以生成超酷的动态布局效果.相信 ...
- 关于Unity中的光照(一)
一.光源定义 光源,是一个普通节点加一个Light组件,创建的时候可以直接创建光源节点,也可以先创建一个空节点,再添加Light组件实例. 二.颜色形成 看到的物体颜色受两个很重要的因素的影响,一个是 ...
- 关于Cocos2d-x中坐标系的种类和转换
注意: 当一个节点有一个子节点的时候,如果移动父节点,子节点也会跟着做相应的移动变化,只要被添加到父节点中,子节点就被绑定了,所以子节点的位置,坐标就会被动地变化. 当一个节点有一个子节点的时候,如果 ...
- 【转】Spring 的下载、安装和使用
一.下载 Spring 下载地址:http://repo.spring.io/libs-release-local/org/springframework/spring/4.0.6.RELEASE/ ...
- -lpthread和-pthread的区别
编译程序包括 预编译, 编译,汇编,链接,包含头文件了,仅能说明有了线程函数的声明, 但是还没有实现, 加上-lpthread是在链接阶段,链接这个库.<stdio.h>等都是静态库,不需 ...