Description

有n个点,第i个点标号为i,有两种操作:
0 x y 表示把x所在堆和y所在堆合并。
1 x 表示询问x所在堆的最小权。

Input

第一行两个整数n,m,表示有n个点m个操作。

接下来m行操作如题。

Output

对于每个询问操作输出其答案。

Sample Input

5 3
1 4
0 2 4
1 4

Sample Output

4
2

HINT

n,m<=100000

Solution

可并堆模板题,看到这道题第一眼裸并查集可做,但为了训练可并堆,此题我们采取可并堆来解决。(虽然还是得用并查集)

用并查集维护每个元素所在堆的根节点,合并即可。注意每次合并的应该是读入元素的根节点,而不是其本身。否则会导致每个点的根节点十分混乱,RE。同时合并的同时应该判断合并的两点是否属于同一个堆,如果是不用再合并,如果不是,则继续合并。

Code

#include <stdio.h>
#include <algorithm>
using namespace std;
int l[],r[],dis[],f[];
int merge(int x,int y)
{
if(!x) return y;
if(!y) return x;
if(x>y)
swap(x,y);
r[x]=merge(r[x],y);
f[r[x]]=x;
if(dis[r[x]]>dis[l[x]])
swap(l[x],r[x]);
dis[x]=dis[r[x]]+;
return x;
}
int find(int x)
{
while(f[x])
x=f[x];
return x;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
dis[]=-;
for(int i=;i<=m;i++)
{
int a;
scanf("%d",&a);
if(a==)
{
int x,y;
scanf("%d%d",&x,&y);
int t1=find(x);
int t2=find(y);
if(t1!=t2)
merge(t1,t2);
}
if(a==)
{
int x;
scanf("%d",&x);
int t1=find(x);
printf("%d\n",t1);
}
}
}

最新文章

  1. 2014 Multi-University Training Contest 9#6
  2. Android Volley框架的使用(5)
  3. GNU make规则的命令④书写命令
  4. Unity3d 查找所选的是否引用过某资源
  5. 【windows核心编程】线程局部存储TLS
  6. a+b(用子函数)
  7. lightoj1017 dp
  8. 【转】context和getApplicationContext()介绍
  9. 使用Maven快速创建一个SpringMVC工程步骤
  10. Goods transportation
  11. BZOJ 3101: N皇后
  12. webservice学习教程(一):理论
  13. org.springframework.dao.InvalidDataAccessResourceUsageException: Unexpected cursor position change. Spring Batch 错误
  14. 初学Python——集合及其运算
  15. 杨辉三角 II
  16. 【转】IT大牛博客
  17. G2( bizCharts ) React 绘制混合图例
  18. 基于ε-NFA的正则表达式引擎
  19. [leetcode]Largest Rectangle in Histogram @ Python
  20. spring boot项目配置RestTemplate超时时长

热门文章

  1. QQ企业通--客户端登陆模块设计---知识点
  2. mybatis 入门参考
  3. textarea不允许修改大小
  4. python学习第二课——while循环
  5. GIMP
  6. bzoj 2111: [ZJOI2010]Perm 排列计数
  7. ng -----监听变化($scope.$watch())
  8. Lesson 48 Planning a share portfolio
  9. PAT (Advanced Level) 1136~1139:1136模拟 1137模拟 1138 前序中序求后序 1139模拟
  10. 51nod 1445:变色DNA 最短路变形