POJ1988 Cube Stacking 【并查集】
题目链接:http://poj.org/problem?id=1988
这题是教练在ACM算法课上讲的一道题,当时有地方没想明白,现在彻底弄懂了。
题目大意:n代表有n个石头,M a, b代表将a石头所在的集合放在b石头所在的所有集合的上方。C a代表询问a石头下方有多少个石头。
思路:
1.一开始我是想用一个 num 数组来表示每块石头下方有多少个石头,然后直接用并查集来写,但是发现最终不能实现,因为只用一个num数组只能保证每个集合的最顶端的石头num值是正确的。
2.正解是用一个 dis 数组代表每块石头到根节点石头的距离,num数组代表每块石头所在集合的石头总数,最终答案就是 num[find(a)] - dis[a] - 1;
3.需要注意的地方是 先查找根节点 后更新dis以及num,因此在查询某一块石头下面有多少石头时,还需要进行一次 find 来更新一下路径上石头的dis。
代码里的注释写的很详细
代码:
注意:数据好像比题面给的大,数组要开大点。
#include<iostream> //用cin输入无视空格和回车,方便判断操作
using namespace std; int num[], pre[], dis[]; int find(int x)
{
if(pre[x] == x)
return x;
else
{
int root = find(pre[x]);
dis[x] += dis[pre[x]];//下面的块中点到新根节点的距离为 原来的距离dis[x]加上被更新过的dis[root] = num[x]的距离
pre[x] = root;
return pre[x];
}
} int main()
{
cin.sync_with_stdio(false);//关闭cin同步加速,但读入只能用cin了
int n;
cin >> n;
for(int i = ; i <= n; i ++)
{
pre[i] = i;
dis[i] = ;//到根节点的距离
num[i] = ;//每个块中包含的点数目
}
while(n --)
{
char ch;
cin >> ch;
if(ch == 'M')
{
int a, b;
cin >> a >> b;
int x = find(a), y = find(b);//此时的find只是找到根节点,find()函数中各点dis值没有改变,因为此时根节点的dis为0
if(x != y)
{//注意顺序
dis[y] = num[x];//这里才给根节点的dis值进行了更新,所以下次还需要调用一次find才能维护各点的dis值
num[x] += num[y];//以x为根节点的块中数目更新为 以x和y为根节点的两个块中点的数目之和
pre[y] = x;
}
}
else if(ch == 'C')
{
int a;
cin >> a;
int x = find(a);//查询之前还需要进行一次 find 来更新块中各点的dis值
printf("%d\n", num[x] - dis[a] - );
}
}
return ;
}
POJ1988
POJ1988 Cube Stacking 【并查集】的更多相关文章
- POJ1988(Cube Stacking)--并查集
题目链接:http://poj.org/problem?id=1988 题意:有n个元素,开始每个元素各自在一个栈中,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈. 第二种操作是询问 ...
- poj.1988.Cube Stacking(并查集)
Cube Stacking Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Submi ...
- poj1988 Cube Stacking 带权并查集
题目链接:http://poj.org/problem?id=1988 题意:有n个方块,编号为1-n,现在存在两种操作: M i j 将编号为i的方块所在的那一堆方块移到编号为j的方块所在的那 ...
- poj1988 Cube Stacking(并查集
题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[ ...
- poj1988 Cube Stacking
并查集的高效之处在于路径压缩和延迟更新. 在本题中需要额外维护子树的规模以及当前子树节点到跟的距离两个数组. 由于一个新的数必然是两棵树拼接而成,对于子树规模的更新直接相加即可, 对于节点到跟的距离: ...
- POJ1988 Cube stacking(非递归)
n有N(N<=30,000)堆方块,开始每堆都是一个方块.方块编号1 – N. 有两种操作: nM x y : 表示把方块x所在的堆,拿起来叠放到y所在的堆上. nC x : 问方块x下面有多少 ...
- POJ 1988 Cube Stacking(并查集+路径压缩)
题目链接:id=1988">POJ 1988 Cube Stacking 并查集的题目 [题目大意] 有n个元素,開始每一个元素自己 一栈.有两种操作,将含有元素x的栈放在含有y的栈的 ...
- bzoj3376/poj1988[Usaco2004 Open]Cube Stacking 方块游戏 — 带权并查集
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3376 题目大意: 编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方 ...
- POJ 1988 Cube Stacking( 带权并查集 )*
POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...
随机推荐
- nginx配置项
try_files location / { try_files $uri $uri/ /index.php?$query_string; } 当用户请求 http://host/instance时, ...
- Spring MVC ajax提交方式
使用jquery的ajax的方式来提交 第一种,以json对象的形式提交 var jsonData = { "name" : "zhangsan", " ...
- Laravel学习笔记之PHP反射(Reflection) (上)
Laravel学习笔记之PHP反射(Reflection) (上) laravel php reflect 2.1k 次阅读 · 读完需要 80 分钟 3 说明:Laravel中经常使用PHP的反 ...
- ubuntu配置pip3以及scrapy
.安装支持pip3 sudo apt-get install python3-pip .安装scrapy 首先需要安装scrapy依赖项,否则scrapy安装失败,执行如下命令: sudo apt-g ...
- 单链表之Java实现
初次接触java,用java也写了一个链表.代码如下: import java.io.*; class Node{ public int data; //数据域 public Node next; / ...
- quartz中的corn表达式
一个Quartz的CronTrigger表达式分为七项子表达式,其中每一项以空格隔开,从左到右分别是:秒,分,时,月的某天,月,星期的某天,年:其中年不是必须的,也就是说任何一个表达式最少需要六项! ...
- idea git操作 -- 已有项目添加到git
我们在使用git时,如果是先从git克隆项目,然后配置项目运行没问题,如果将已有项目添加到git,则项目环境还是提交不了git,还需要到克隆的仓库文件夹打开项目去操作git,如果有有类型情况可按照如下 ...
- nginx配置, 启动命令, 反向代理配置
2014年1月3日 13:52:07 喜欢这样的风格,干货 http://huoding.com/2013/10/23/290 -----------------下边是我自己的经验(windows)- ...
- Spring配置文件里加载路径中的通配符
?代表匹配任意一个字符 *代表匹配0个或多个任意字符 **/匹配任意多个目录 classpath:app-Beans.xml 查找app-Beans.xm ...
- 从源码学习使用 node-delegates
node-delegates 是 TJ 大神所写的一个简单的小工具,源码只有 157 行,作用在于将外部对象接受到的操作委托到内部属性进行处理,也可以理解为讲对象的内部属性暴露到外部,简化我们所需要书 ...