I hope you know the beautiful Union-Find structure. In this problem, you’re to implement somethingsimilar, but not identical.The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:1 p q Union the sets containing p and q. If p and q are already in the same set,ignore this command.2 p q Move p to the set containing q. If p and q are already in the same set,ignore this command.3 p Return the number of elements and the sum of elements in the set containingp.Initially, the collection contains n sets: {1}, {2}, {3}, . . . , {n}.InputThere are several test cases. Each test case begins with a line containing two integers n and m(1 ≤ n, m ≤ 100, 000), the number of integers, and the number of commands. Each of the next m linescontains a command. For every operation, 1 ≤ p, q ≤ n. The input is terminated by end-of-file (EOF).OutputFor each type-3 command, output 2 integers: the number of elements and the sum of elements.ExplanationInitially: {1}, {2}, {3}, {4}, {5}Collection after operation 1 1 2: {1,2}, {3}, {4}, {5}Collection after operation 2 3 4: {1,2}, {3,4}, {5} (we omit the empty set that is produced whentaking out 3 from {3})Collection after operation 1 3 5: {1,2}, {3,4,5}Collection after operation 2 4 1: {1,2,4}, {3,5}Sample Input5 71 1 22 3 41 3 53 42 4 13 43 3Sample Output3 123 72 8

AC代码为:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 1e5 + 10;
int father[maxn], id[maxn], sum[maxn], cnt[maxn];
int n, m, p, q, dt, temp;

int Find(int a)
{
return a == father[a] ? a : Find(father[a]);
}

void Union_set(int a, int b)
{
int x = Find(a);
int y = Find(b);
if (x != y)
{
father[y] = x;
cnt[x] += cnt[y];
sum[x] += sum[y];
}
}

void Move_set(int a)
{
int fa = Find(id[a]);
sum[fa] -= a;
cnt[fa]--;
id[a] = ++temp;
father[id[a]] = temp;
cnt[id[a]] = 1;
sum[id[a]] = a;
}

int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
temp = n;
for (int i = 0; i <= n; i++)
{
father[i] = i;
sum[i] = i;
id[i] = i;
cnt[i] = 1;
}
while (m--)
{
cin >> dt;

if (dt == 1)
{
cin >> p >> q;
Union_set(id[p], id[q]);

}
else if (dt == 2)
{
cin >> p >> q;
int t1 = Find(id[p]);
int t2 = Find(id[q]);
if (t1 != t2)
{
Move_set(p);
Union_set(id[p], id[q]);
}

}
else
{
cin >> p;
int fat = Find(id[p]);
cout << cnt[fat] << " " << sum[fat] << endl;
}
}

}

return 0;
}

UVA-11987的更多相关文章

  1. UVA - 11987 Almost Union-Find[并查集 删除]

    UVA - 11987 Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, y ...

  2. UVA 11987 - Almost Union-Find(并查集)

    UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...

  3. UVa 11987 Almost Union-Find(支持删除操作的并查集)

    传送门 Description I hope you know the beautiful Union-Find structure. In this problem, you’re to imple ...

  4. UVA 11987 Almost Union-Find (并查集+删边)

    开始给你n个集合,m种操作,初始集合:{1}, {2}, {3}, … , {n} 操作有三种: 1 xx1 yy1 : 合并xx1与yy1两个集合 2 xx1 yy1 :将xx1元素分离出来合到yy ...

  5. 并查集(删除) UVA 11987 Almost Union-Find

    题目传送门 题意:训练指南P246 分析:主要是第二种操作难办,并查集如何支持删除操作?很巧妙的方法:将并查集树上p的影响消除,即在祖先上(sz--, sum -= p),然后为p换上马甲:id[p] ...

  6. uva 11987 Almost Union-Find (并检查集合)

    标题效果: 三操作. 1. 合并两个集合 2.代替所述第二组的第一个元素 3.输出设置数量,并.. IDEAS: 使用p该元素的记录数,其中集合,建立并查集. #include <cstdio& ...

  7. UVa 11987 Almost Union-Find (虚拟点)【并查集】

    <题目链接> 题目大意: 刚开始,1到n个集合中分别对应着1~n这些元素,然后对这些集合进行三种操作: 输入 1 a b 把a,b所在的集合合并 输入 2 a b 把b从b所在的旧集合移到 ...

  8. UVA - 11987 Almost Union-Find(带删除的并查集)

    I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something s ...

  9. UVA 11987 Almost Union-Find (单点修改的并查集)

    此题最难处理的操作就是将一个单点改变集合,而普通的并查集是不支持这种操作的. 当结点p是叶子结点的时候,直接pa[p] = root(q)是可以的, p没有子结点,这个操作对其它结点不会造成任何影响, ...

  10. UVA - 11987 Almost Union-Find 并查集的删除

    Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, you're to imp ...

随机推荐

  1. 新手小白的Linux学习之路

    大家好,我是一个零基础的新手小白,在此和大家分享一下新手小白的学习之路.欢迎各位大神指教!谢谢 Linux简介: Linux操作系统诞生于1991年10月,由芬兰赫尔辛基大学的在校生Linus Tor ...

  2. Fuzzy模糊推导(Matlab实现)

    问题呈述 在模糊控制这门课程中,学到了与模糊数学及模糊推理相关的内容,但是并不太清楚我们在选择模糊规则时应该如何处理,是所有的规则都需要由人手工选择,还是仅需要选择其中的一部分就可以了.因此,在课程示 ...

  3. Mybatis实现数据的增删改查

    Mybatis实现数据的增删改查 1.项目结构(使用maven创建项目) 2.App.java package com.GetcharZp.MyBatisStudy; import java.io.I ...

  4. x86汇编分页模式实验 --《ORANGE'S一个操作系统的实现》中 pmtest8.asm解析

    序言(废话) : 在看书的过程中发现一开始不是很能理解pmtest8的目的,以及书上说得很抽象..于是在自己阅读过源代码后,将一些自己的心得写在这里. 正文 : 讲解顺序依然按照书上贴代码的顺序来.但 ...

  5. Ubuntu改坏sudoers后无法使用sudo的解决办法

    练习安装odoo的时候,创建了一个odoo用户,想把它赋予sudo权限,然而,编辑的时候不留意,改坏了,导致sudo无法使用,无法编辑sudoers文件修改回来. 总提示如下信息: >>& ...

  6. python容器类型字典的操作

    字典(dict):由大括号进行描述一组键值对,其键值对之间使用冒号隔开,键值对与键值对之间使用逗号隔开: 注意:字典的key可以为数字,但是不可以重复,因为key是唯一标识符: 1.声明一个字典:语法 ...

  7. GeoServer 安装教程

    准备内容 安装环境:win10*64位专业版 安装文件:geoserver-2.15.2 安装步骤 安装JDK 1.安装GeoServer是基于Java的环境,所以需要先装Jdk环境. 2.前往官网下 ...

  8. 给公司写的composer包开发的规范

    版本格式 主版本号.次版本号.修订号 版本号递增规则 主版本号:当你做了不兼容的 API 修改 次版本号:当你做了向下兼容的功能性新增 修订号:当你做了向下兼容的问题修正 先行版本号及版本编译元数据可 ...

  9. oracle插入,更新,删除数据

    插入,更新,删除数据 oracle提供了功能丰富的数据库管理语句 包括有效的向数据库中插入数据的insert语句 更新数据的update语句 以及当数据不再使用时删除数据的delete语句 更改数据之 ...

  10. python 安装resquest

    本文链接:https://blog.csdn.net/charlotte1516/article/details/91991848 搬运是为了怕原链接失效,建议浏览原链接. 1.首先在开始栏搜索cmd ...