题目大意

开始有N堆砖块,编号为1,2....N,每堆都只有一个。之后可以进行两种操作: 
(1)M X Y 将编号为X的砖块所在的那堆砖拿起来放到编号为Y的砖块所在的堆上; 
(2)C X 查询编号为X的砖块所在的堆中,在砖块X下方的所有砖块的数目

题目分析

典型的集合合并和查询,因此采用并查集。并查集的基本框架就是一个GetPar函数(实现查找集合的祖先,同时实现路径压缩),一个Union函数(实现将两个集合合并),一个SameGroup函数(判断两个元素是否属于同一个集合)。 
    在利用并查集解决具体问题的时候,需要做的是设置一个数据结构用于存放问题所需要的信息,然后在GetPar函数和Union函数中更新这个数据结构。 
    在本题中,维护信息 SumOfStack(每堆中的所有砖块数目),NumOfUnderBlock(堆中在砖块下方的砖块数目)。将每堆砖块集合的编号(即集合的根)设置为该堆最下方的砖块号,则在合并的时候,上堆的根节点的父节点设置为下堆的根节点,可以更新的数据为上堆的根节点下方的砖块数目下堆的根节点代表的堆总砖块数。 
    这样,每堆的根节点的SumOfStack信息是正确的,而每次合并后上堆的原根节点的NumOfUnderBlock信息也是正确的;对于某个砖块b,在GetPar的过程中,由于b的gPar[b]可能没被更新,如果没被更新,则b的NumOfUnderBlock[b]表示在b之前所在的堆中位于b下方的砖块数目也是正确的,于是将此时的NumOfUnderBlock[b] + NumOfUnderBlock[gPar[b]](注意,这里的gPar[b]为b原来的堆中的根),即可得到最终的NumOfUnderBlock[b],这可以在GetPar函数的递归中完成。

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX_STACK_NUM 30001
int gPar[MAX_STACK_NUM];
int gSumOfStack[MAX_STACK_NUM];
int gNumOfUnderBlock[MAX_STACK_NUM]; int GetPar(int c){
if (c != gPar[c]){
int p = gPar[c];
gPar[c] = GetPar(gPar[c]); //信息维护
gNumOfUnderBlock[c] += gNumOfUnderBlock[p];
}
return gPar[c];
} void Union(int a, int b){
int p1 = GetPar(a);
int p2 = GetPar(b);
gPar[p1] = p2; //信息维护
gNumOfUnderBlock[p1] = gSumOfStack[p2];
gSumOfStack[p2] += gSumOfStack[p1];
} void Init(){
for (int i = 0; i < MAX_STACK_NUM; i++){
gSumOfStack[i] = 1;
gNumOfUnderBlock[i] = 0;
gPar[i] = i;
}
}
int main(){
int p, X, Y;
scanf("%d", &p);
char op;
Init();
for (int i = 0; i < p; i++){
getchar();
scanf("%c", &op);
if (op == 'M'){
scanf("%d %d", &X, &Y);
Union(X, Y);
}
else if (op == 'C'){
scanf("%d", &X);
GetPar(X);
printf("%d\n", gNumOfUnderBlock[X]);
}
}
return 0;
}

poj_1988 并查集的更多相关文章

  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编译配置

    1.  下载Busybox tar包,如busybox-1.23.0.tar.bz2. 官网:http://www.busybox.net/ 2.   make distclean:清除原有配置 ma ...

  2. golang第三方日志包seelog配置文件详解

    开发任何项目,都离不开日志,配好自己的项目日志输出,往往是开发项目的前提.在golang中,seelog应该是比较有名的日志处理包了,功能非常强大,seelog官方文档 一.seelog主要功能下面我 ...

  3. position属性absolute(绝对定位),relatve(相对定位)

    position:absolute这个是绝对定位:是相对于浏览器的定位. position:relative这个是相对定位:是居于上一个流体而言

  4. 关于Cocos2d-x中父子节点的互动

    1.子节点可以通过this->getParent()来获得相应的父节点,并且进行强制类型转换. ((Scene*)this->getParent())->getPhysicsWorl ...

  5. windows下定时任务设置

    Linux 系统可以通过crontab -e 设置定时任务,Windows系统没有crontab命令,但是Windows系统有跟crontab命令比较接近的命令: schtasks 命令. # 设置定 ...

  6. TinyOS节点间通信相关接口和组件介绍

    一.基本通信接口:   Packet:提供了对message_t抽象数据类型的基本访问.这个接口的命令有:清空消息内容,获得消息的有效载荷区长度,获得消息有效载荷区的指针. //tos/interfa ...

  7. c++ double float 数值比较

    浮点数在内存中的存储机制和整型数不同,其有舍入误差,在计算机中用近似表示任意某个实数.具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基 ...

  8. 解决myeclipse4.1.1对一个表生成映射文件的时候,出现“generating artifacts"的解决!

    很多人在用myeclipse4.1.1对一个表生成映射文件的时候,都出现“generating artifacts"的问题.我也遇到了这个问题,弄得我也很郁闷!看了很多人的帖子后还是无法搞定 ...

  9. 安装JDK出现问题 Error opening registry key'software\Javasoft\Java Runtime Environment'

    第一次安装JDK测试是否安装成功,打开cmd输入java -version 回车的时候出现如下错误: Error opening registry key'software\Javasoft\Java ...

  10. cocos2d 中使用jni C++ 调用 Java 方法

    1.简单数据类型样例 如果我们Java中有这么一个open的静态方法,它没有參数,有一个int的返回值.怎么在C++中调用它呢? package cb.CbCCBLE; public class Cb ...