题目链接: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 【并查集】的更多相关文章

  1. POJ1988(Cube Stacking)--并查集

    题目链接:http://poj.org/problem?id=1988 题意:有n个元素,开始每个元素各自在一个栈中,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈. 第二种操作是询问 ...

  2. poj.1988.Cube Stacking(并查集)

    Cube Stacking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submi ...

  3. poj1988 Cube Stacking 带权并查集

    题目链接:http://poj.org/problem?id=1988 题意:有n个方块,编号为1-n,现在存在两种操作: M  i  j  将编号为i的方块所在的那一堆方块移到编号为j的方块所在的那 ...

  4. poj1988 Cube Stacking(并查集

    题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[ ...

  5. poj1988 Cube Stacking

    并查集的高效之处在于路径压缩和延迟更新. 在本题中需要额外维护子树的规模以及当前子树节点到跟的距离两个数组. 由于一个新的数必然是两棵树拼接而成,对于子树规模的更新直接相加即可, 对于节点到跟的距离: ...

  6. POJ1988 Cube stacking(非递归)

    n有N(N<=30,000)堆方块,开始每堆都是一个方块.方块编号1 – N. 有两种操作: nM x y : 表示把方块x所在的堆,拿起来叠放到y所在的堆上. nC x : 问方块x下面有多少 ...

  7. POJ 1988 Cube Stacking(并查集+路径压缩)

    题目链接:id=1988">POJ 1988 Cube Stacking 并查集的题目 [题目大意] 有n个元素,開始每一个元素自己 一栈.有两种操作,将含有元素x的栈放在含有y的栈的 ...

  8. bzoj3376/poj1988[Usaco2004 Open]Cube Stacking 方块游戏 — 带权并查集

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3376 题目大意: 编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方 ...

  9. POJ 1988 Cube Stacking( 带权并查集 )*

    POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...

随机推荐

  1. JVM(十二),垃圾回收面试题

    十二.垃圾回收面试题 1.Object的finalize()方法 2.Java中的强软弱虚四种引用 (1)强引用 (2)软引用(间接引用) (3)弱引用 (4)虚引用 (5)四种引用区别

  2. I am coming..

    It's so great to start the blog here since it's been a long time that I want to start such kind of l ...

  3. Python相关分析—一个金融场景的案例实操

    哲学告诉我们:世界是一个普遍联系的有机整体,现象之间客观上存在着某种有机联系,一种现象的发展变化,必然受与之关联的其他现象发展变化的制约与影响,在统计学中,这种依存关系可以分为相关关系和回归函数关系两 ...

  4. sql到python正则

    import urllib.requestimport re,timeresult=[]for i in range(100):    urls ="http://xxx.com/-1%20 ...

  5. Leetcode题目56.合并区间(中等)

    题目描述: 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 ...

  6. Final——PowerShell Empire

    一.介绍 Empire是一款针对Windows平台的.使用PowerShell脚本作为攻击载荷的渗透攻击框架工具,具有从stager生成.提权到渗透维持的一系列功能.Empire实现了无需powers ...

  7. 带有时间间隔的dp

    Uberwatch 题意:一个人打一群敌人,每间隔时间m能释放一次大招,消灭这个时刻上的所有敌人,起始时刻开始计算冷却时间 solution: dp[i]=max(dp[i],dp[i-m]); /* ...

  8. map,实现技巧,id

    cf #include<iostream> #include<cstdio> #include<algorithm> #include<vector> ...

  9. Ubuntu 配置ISCSI服务

    摘要:sudo apt-get install iscsitarget立刻搞定, 然后编辑配置文件:sudovim/etc/ietd.conf默认的配置文件, 有详细的配置说明和示例,本博先备份了事, ...

  10. 自动更新文件夹下所有DLL 至最新修改时间版本

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...