题目链接:http://poj.org/problem?id=1988

题意:有n个元素,开始每个元素各自在一个栈中,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈。
第二种操作是询问含有x元素下面有多少个元素。
思路:

并查集,把每一堆看作一个栈,堆的下方看作栈顶。因为当我们知道栈中元素的总数,和某元素到“栈顶”的距离,
我们就能知道这个元素下面有多少元素。合并操作的时候,始终使用在下面栈的根来做合并之后的根,这样也就达到了栈中的根是栈中的“栈顶”元素的效果,我们只需在每个“栈顶”中记录该栈中的元素总数即可。然而我们还需要得知某元素到“栈顶”的距离,这样我们就需要记录每个元素到其父亲的距离,把它到根上所经过的距离加起来,即为它到“栈顶”的距离。这样我们就得出了结果。
 
这个图是在合并的时候的关键部分 
另外,在进行Find()操作时,有一句 under[x] += under[t[x].parent];这句话就是在递归寻找根结点时,计算出每个元素距离栈底(根)的距离。
 #include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<string>
#include<algorithm>
#include<iomanip>
using namespace std; struct node
{
int parent;
int date;
}; int * total;
int * under; class DisJoinSet
{
protected:
int n; node * tree;
public:
DisJoinSet(int n);
~DisJoinSet();
void Init();
int Find(int x);
void Union(int x,int y);
}; DisJoinSet::DisJoinSet(int n)
{
this->n = n;
tree = new node[n+];
total = new int[n+];
under = new int[n+];
Init();
}
DisJoinSet::~DisJoinSet()
{
delete[] under;
delete[] total;
delete[] tree;
} void DisJoinSet::Init()
{
for(int i = ;i <= n ;i ++)
{
tree[i].date = i;
tree[i].parent = i;
total[i] = ;
under[i] = ;
}
}
int DisJoinSet::Find(int x)
{
//int temp = tree[x].parent;
if(x != tree[x].parent)
{
int par = Find(tree[x].parent);
under[x] += under[tree[x].parent];//把父亲结点下面的个数加到自己头上
tree[x].parent = par;
return tree[x].parent;
}
else
{
return x;
}
} void DisJoinSet::Union(int x,int y)
{
int pa = Find(x);
int pb = Find(y);
if(pa == pb)return ;
else
{
tree[pa].parent = pb;//x的根变为y的根 即把x所在的堆放在y所在的堆上面
under[pa] = total[pb];//pa下的数量即原来y所在栈里的元素total
total[pb] += total[pa];//更新y的totoal
}
} int main()
{
int p;
while(scanf("%d",&p) != EOF)
{
if(p == )break;
DisJoinSet dis(p);
char s1[];
for(int i = ;i < p ;i++)
{ int s2;
int s3;
scanf("%s",s1);
if(s1[] == 'M')
{
scanf("%d%d",&s2,&s3);
int pa = dis.Find(s2);
int pb = dis.Find(s3);
if(pa != pb)
{
dis.Union(s2,s3);
}
}
if(s1[] == 'C')
{
scanf("%d",&s2);
dis.Find(s2);
cout<<under[s2]<<endl;
}
}
dis.~DisJoinSet();
}
return ;
}

最新文章

  1. NOIP 2014 Day2 T1 无线网络发射器
  2. 二模12day2解题报告
  3. PS------“窗口” -&gt; &quot;扩展功能&quot;使用方法
  4. testNG设置测试的执行顺序
  5. css显示出三角形
  6. PCL—低层次视觉—关键点检测(rangeImage)
  7. 【Spark学习】Apache Spark for 第三方Hadoop分发版
  8. WordPress RokMicroNews插件‘thumb.php’ 多个安全漏洞
  9. Effective Java 第三版——8. 避免使用Finalizer和Cleaner机制
  10. CodeForces - 730A 贪心+模拟
  11. Evensgn 剪树枝 树规
  12. linux 的基础命令
  13. Javascript数组系列四之数组的转换与排序Sort方法
  14. python变量传递
  15. HTTP GET的VC三种方式
  16. SpringBoot 1.快速搭建一个 SpringBoot Maven工程
  17. hadoop开发环境
  18. JavaScript中map函数和filter的简单举例
  19. slf4j中的Logger 使用占位符{} 来传入参数记录日志信息
  20. yaf学习

热门文章

  1. 猎豹网校C++ Primer学习笔记
  2. Java并发包线程池之ThreadPoolExecutor
  3. 简易的CRM系统案例之Struts2+JSP+MySQL版本
  4. 使用MockMvc进行springboot调试(SpringbootTest)
  5. MySQL高性能优化指导思路
  6. ElasticSearch文档删除字段
  7. js 高级程序设计 第四章学习笔记
  8. laravel 小知识点
  9. 偶尔要用的git命令备忘
  10. [多转合成] 使用pycaffe保存各个层的特征图