思路:

当时只有暴力的思想,1、3都很好达到,只要加一个sum[ ]和num[ ]就可以,但是2比较麻烦,不知道谁以p为根,就想直接扫描然后一个个和p脱离关系,果然超时emmm。通常的想法是我们先用一个数组id[ ]表示p所代表的代号也就是说p当前的根为:

pre[ id[p] ]

所以当p被2操作时,我们只要改变它的id[p](比如 id[p]=++n),我们就可以让p有一个新的pre[ ]表示,而不用改变原来的根的表示,所以当后面的操作又用到p时,现在的 pre[ id[p] ] 已经不是之前那个了。

详细可以看代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#include<map>
#define N 200010
#define HASH 10000
using namespace std;
int pre[N],num[N],id[N];
long long sum[N];
int find(int a){
int r=a;
while(r!=pre[r]){
r=pre[r];
}
int i=a,j;
while(i!=pre[i]){
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void init(int n){
int i;
for(i=0;i<=n;i++){
pre[i]=i;
sum[i]=i;
id[i]=i;
num[i]=1;
}
}
int join(int p,int q){ //合并两个根(注意:方向必须是这样)
int fp=find(id[p]);
int fq=find(id[q]);
pre[fp]=fq;
num[fq]+=num[fp];
sum[fq]+=sum[fp];
}
int main(){
int n,m,c,p,q,i;
while(scanf("%d%d",&n,&m)!=EOF){
init(n);
while(m--){
scanf("%d",&c);
if(c==1){
scanf("%d%d",&p,&q);
if(find(id[p])!=find(id[q]))
join(p,q);
}
else if(c==2){
scanf("%d%d",&p,&q);
if(find(id[p])!=find(id[q])){
num[find(id[p])]--; //脱离与原根关系
sum[find(id[p])]-=p;
id[p]=++n; //重新申请一个id
pre[id[p]]=id[p]; //初始化
sum[id[p]]=p;
num[id[p]]=1;
join(p,q); //建立新关系
}
}
else{
scanf("%d",&p);
printf("%d %d\n",num[find(id[p])],sum[find(id[p])]);
}
}
}
return 0;
}

Almost Union-Find (并查集+删除元素)题解的更多相关文章

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

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

  2. Hdu 2473(并查集删除操作) Junk-Mail Filter

    有木有非常吊 加强 加强版   啊  ,看了都不敢做了   .后来先做了食物链这个我还是看过的.但还是A不掉,没明确神魔意思 .总而言之.大牛的博客是个好东西.我就那么看了一下,还是不懂怎莫办啊,哎, ...

  3. HDU 2473 Junk-Mail Filter 【并查集删除】

    Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. hdu2473 Junk-Mail Filter 并查集+删除节点+路径压缩

    Description Recognizing junk mails is a tough task. The method used here consists of two steps:  1) ...

  5. HDU 2473 Junk-Mail Filter 并查集删除(FZU 2155盟国)

    http://acm.hdu.edu.cn/showproblem.php?pid=2473 http://acm.fzu.edu.cn/problem.php?pid=2155 题目大意: 编号0~ ...

  6. UVA11987Almost Union-Find(并查集删除节点)

    题目链接 题意:n个数(即1-n)和m个操作: 1表示把x和y合并,2表示把x移到y集合里面,3表示统计x集合的元素个数 1,3好说,关键是2操作,可以先把2删除掉,删除的操作可以找一个其他的数字来取 ...

  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. 第十四届华中科技大学程序设计竞赛 C Professional Manager【并查集删除/虚点】

    题目描述 It's universally acknowledged that there're innumerable trees in the campus of HUST. Thus a pro ...

  9. <算法><Union Find并查集>

    Intro 想象这样的应用场景:给定一些点,随着程序输入,不断地添加点之间的连通关系(边),整个图的连通关系也在变化.这时候我们如何维护整个图的连通性(即判断任意两个点之间的连通性)呢? 一个比较简单 ...

随机推荐

  1. python ---多进程 Multiprocessing

    和 threading 的比较 多进程 Multiprocessing 和多线程 threading 类似, 他们都是在 python 中用来并行运算的. 不过既然有了 threading, 为什么 ...

  2. 5.JVM的内存区域划分

    一.JVM介绍 1. 什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟 ...

  3. java 使用jacob把word转pdf

    一.使用前要下载必要包及文件 链接: https://pan.baidu.com/s/1nvutQxb 密码: qgpi 二.引包和dll文件 1.引包:eclipse引包就不用说了,idea引包步骤 ...

  4. 使用函数接口和枚举实现配置式编程(Java与Scala实现)

    概述 做报表时,有时需要根据不同的业务生成不同的报表.这样,需要能够动态地配置列字段,并根据列字段来输出对应的报表.使用函数接口结合枚举可以比较优雅地实现配置式编程. 问题描述如下: 假设有对象 St ...

  5. Hive 修改表结构常用操作

    添加列  add columns alter table table_name add columns (id int comment '主键ID' ) ; 默认在表所有字段之后,分区字段之前. 替换 ...

  6. python的print函数自动换行及其避免

    print函数自带换行功能,即在输出内容后会自动换行,但是有时我们并不需要这个功能,那怎么办呢?这时候就需要用到end这个参数了,使用方法参考下面这段打印$矩阵的代码: i = 1 while i&l ...

  7. USB接口案例——多态和转型

    其中,为传递和使用的匿名对象,即创建了对象,但是没有引用类和对象名来接收: 电脑类中的操作usb的成员方法中,要向下转型,毛主席讲的具体问题具体分析,不同的设备有不同的操作:

  8. Linux服务器配置---安装nfs

    安装nfs NFS是Network File System的缩写,即网络文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. 由于NFS支持的功能很多,不同功能会使用不同程序 ...

  9. .NET创建一个即是可执行程序又是Windows服务的程序

    不得不说,.NET中安装服务很麻烦,即要创建Service,又要创建ServiceInstall,最后还要弄一堆命令来安装和卸载. 今天给大家提供一种方式,直接使用我们的程序来安装/卸载服务,并且可以 ...

  10. Elasticsearch集群内的原理

        一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力.当有节点加入集群中或者从 ...