<题目链接>

题目大意:

刚开始,1到n个集合中分别对应着1~n这些元素,然后对这些集合进行三种操作:

输入 1 a b 把a,b所在的集合合并 
输入 2 a b 把b从b所在的旧集合移到a的集合中 
输入 3 a 输出a所在集合的元素个数和这个集合的元素和。

解题分析:

1,3操作容易实现,但是2操作,如果仅仅只是简单的将father[a]=find(b) 的话,就错了,因为a可能恰好为那个集合的根节点,那么这种做法会将a的所有子节点也全部移动到b集合。因此,我们并不对a进行真正物理位置上的移动,而是假设a移动到了b集合,在b集合加入a的一个虚拟点,模拟a移动到b集合,实际上a还在原来的集合待着,但是这时,原来的a已经不会对本题产生任何影响,因为此时,两个集合所维护的两个值正常更新,并且我们认为a已经移动到了b , a的 id 也从原来的位置变到了新分配到的位置。通过这个虚拟点的建立,我们就能够模拟a移动到b集合的操作。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

;
int n,m,pos;
int father[M],sum[M],tot[M],id[M];

void init(){
    ;i<M;i++){
        father[i]=i;
        sum[i]=i;    //该集合所有元素总和
        tot[i]=;    //该集合元素个数
        id[i]=i;     //为i的实际所在位置(假设真的进行物理位置上的移动)
    }
    pos=n;
}
int find(int x){
    if(father[x]==x)return x;
    father[x]=find(father[x]);
    return father[x];
}
void Union(int x,int y){
    int f1=find(x),f2=find(y);
    if(f1!=f2){
        father[f1]=f2;
        tot[f2]+=tot[f1];   //更新这两个值
        sum[f2]+=sum[f1];
    }
}
//将a移动到b的集合
void Move(int a,int b){   //只进行数值上的虚拟移动,而不进行点的位置移动,即,移完后,a还在原来的集合,但是对结果不产生影响,同时我们假装a已经移动到了id[i]这个点
    int f1=find(id[a]),f2=find(b);   //因为b传过来的是真实的位置
    if(f1!=f2){
        tot[f2]++,tot[f1]--;     //模拟移动,更新这两个集合根节点维护的值
        sum[f2]+=a,sum[f1]-=a;
        id[a]=++pos;     //给这个虚拟点分配一个位置
        father[pos]=f2;  //这个虚拟点的father设为f2
    }
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        while(m--){
            int op,a,b;
            scanf("%d%d",&op,&a);
            ){
                scanf("%d",&b);
                Union(id[a],id[b]);
            }
            ){
                scanf("%d",&b);
                Move(a,id[b]);
            }
            else{
                int root=find(id[a]);
                printf("%d %d\n",tot[root],sum[root]);
            }
        }
    }
    ;
}

2018-10-04

UVa 11987 Almost Union-Find (虚拟点)【并查集】的更多相关文章

  1. UVA 1664 Conquer a New Region (并查集+贪心)

    并查集的一道比较考想法的题 题意:给你n个点,接着给你n-1条边形成一颗生成树,每条边都有一个权值.求的是以一个点作为特殊点,并求出从此点出发到其他每个点的条件边权的总和最大,条件边权就是:起点到终点 ...

  2. UVA - 10129 Play on Words(欧拉回路+并查集)

    2.解题思路:本题利用欧拉回路存在条件解决.可以将所有的单词看做边,26个字母看做端点,那么本题其实就是问是否存在一条路径,可以到达所有出现过的字符端点.由于本题还要求了两个单词拼在一起的条件是前一个 ...

  3. UVA - 208 Firetruck(消防车)(并查集+回溯)

    题意:输入着火点n,求结点1到结点n的所有路径,按字典序输出,要求结点不能重复经过. 分析:用并查集事先判断结点1是否可以到达结点k,否则会超时.dfs即可. #pragma comment(link ...

  4. UVA - 10129 Play on Words (欧拉回路+并查集)

    思路: 分别存下每个字符串的首尾字符,以字符为结点,单词看作一条变,就变成了求欧拉回路了,先判断下图是否连通,然后根据欧拉回路的结论:最多只能有两个点的入读不等于初读,而且必须是一个点的出度恰好比入度 ...

  5. UVa 1395 苗条的生成树(Kruskal+并查集)

    https://vjudge.net/problem/UVA-1395 题意: 给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 思路: 主要还是克鲁斯卡尔算法,先仍是按权值排序,对 ...

  6. UVa 1664 Conquer a New Region(并查集)

    https://vjudge.net/problem/UVA-1664 题意: n个城市形成一棵树,每条边有权值C(i,j).任意两个点的容量S(i,j)定义为i与j唯一通路上容量的最小值.找一个点, ...

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

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

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

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

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

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

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

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

随机推荐

  1. SoapUI、Jmeter、Postman三种接口测试工具的比较分析

    前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...

  2. selenium 获取input输入框中的值的方法

    方法一:获取input的文本值 <input class="form-text-normal" id="txtName" name="Name& ...

  3. PHP实现网络Socket及IO多路复用

    一直以来,PHP很少用于socket编程,毕竟是一门脚本语言,效率会成为很大的瓶颈,但是不能说PHP就无法用于socket编程,也不能说PHP的socket编程性能就有多么的低,例如知名的一款PHP ...

  4. ubuntu MySQL的安装

    https://i.cnblogs.com/EditPosts.aspx?opt=1 https://juejin.im/entry/5adb5deff265da0b9d77cb3b MySQL Co ...

  5. kali linux revealed mastering the penetration testing distribution

    1.本博客记载的是这本书的学习笔记,还有出现的一些不懂的单词 我也将会记载这篇博客中.记载顺序是按照本书的章节顺序来记载的.最喜欢本书中的一句   you havae no idea how good ...

  6. vue指令问题

    挂载点:最外层标签就是vue实例的挂载点,即id或者类对应的 dom节点 模板:指挂载点内部的内容,在实例里使用template标签来构 建 h1标签放在body里面不使用 “template”是一样 ...

  7. C++ 内链接 外链接

    编译的时候(假如编译器是VS),是以源文件cpp文件为单位,编译成一个个的obj文件,然后再通过链接器把不同的obj文件链接起来.如果一些变量或函数的定义是内连接的话,链接器链接的时候就不会拿它们去与 ...

  8. 论文阅读笔记三十五:R-FCN:Object Detection via Region-based Fully Convolutional Networks(CVPR2016)

    论文源址:https://arxiv.org/abs/1605.06409 开源代码:https://github.com/PureDiors/pytorch_RFCN 摘要 提出了基于区域的全卷积网 ...

  9. .gz解压

    1.今天很神奇我遇到这样的压缩包,啧啧啧,好少见的,记录下 gzip  -d  http_log.gz 这是讲http_log文件解压到当前的路径下

  10. POJ 1002 487-3279(字典树/map映射)

    487-3279 Time Limit: 2000MS        Memory Limit: 65536K Total Submissions: 309257        Accepted: 5 ...