Almost Union-Find (并查集+删除元素)题解
思路:
当时只有暴力的思想,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 (并查集+删除元素)题解的更多相关文章
- 并查集(删除) UVA 11987 Almost Union-Find
题目传送门 题意:训练指南P246 分析:主要是第二种操作难办,并查集如何支持删除操作?很巧妙的方法:将并查集树上p的影响消除,即在祖先上(sz--, sum -= p),然后为p换上马甲:id[p] ...
- Hdu 2473(并查集删除操作) Junk-Mail Filter
有木有非常吊 加强 加强版 啊 ,看了都不敢做了 .后来先做了食物链这个我还是看过的.但还是A不掉,没明确神魔意思 .总而言之.大牛的博客是个好东西.我就那么看了一下,还是不懂怎莫办啊,哎, ...
- HDU 2473 Junk-Mail Filter 【并查集删除】
Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- hdu2473 Junk-Mail Filter 并查集+删除节点+路径压缩
Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) ...
- 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~ ...
- UVA11987Almost Union-Find(并查集删除节点)
题目链接 题意:n个数(即1-n)和m个操作: 1表示把x和y合并,2表示把x移到y集合里面,3表示统计x集合的元素个数 1,3好说,关键是2操作,可以先把2删除掉,删除的操作可以找一个其他的数字来取 ...
- UVA - 11987 Almost Union-Find[并查集 删除]
UVA - 11987 Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, y ...
- 第十四届华中科技大学程序设计竞赛 C Professional Manager【并查集删除/虚点】
题目描述 It's universally acknowledged that there're innumerable trees in the campus of HUST. Thus a pro ...
- <算法><Union Find并查集>
Intro 想象这样的应用场景:给定一些点,随着程序输入,不断地添加点之间的连通关系(边),整个图的连通关系也在变化.这时候我们如何维护整个图的连通性(即判断任意两个点之间的连通性)呢? 一个比较简单 ...
随机推荐
- Unity之Vector3.SignedAngle实现
如代码: float angle = Vector3.Angle(v1, v2); angle *= Mathf.Sign(Vector3.Cross(v1, v2).y);
- html5-样式表的使用-初步
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- hdu 5126 cdq+Treap+BIT
这题说的是给了三维空间然后操作 寻求在 x1,y1,z1 x2, y2, z2; (x1<x2, y1<y2,z1<z2) 计算出在 以这两个端点为右下和左上端点的方体内的点的 ...
- js三目学习
<script> var n=1; n>1?document.write('大于1哦'):document.write('小于或等于1哦') //n=n>1?document. ...
- Java并发编程:volatile关键字解析-转
Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...
- python 在列表,元组,字典变量前加*号
废话不说,直接上代码(可能很多人以前不知道有这种方法): a=[1,2,3]b=(1,2,3)c={1:"a",2:"b",3:"c"}pr ...
- 接口作为方法的参数或返回值——List接口
接口作为方法的参数或返回值,源码可知,List为一个接口,ArraryList是的它的实现类: 其中,addNames方法中,入参和返回值都List接口,入参是多态的,编译看左,运行看右(访问成员方法 ...
- Codeforces 124A - The number of positions
题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't ...
- 直播协议的选择:RTMP vs. HLS
文章转自:直播协议的选择:RTMP vs. HLS 前言 随着直播业务的兴起,越来越多的直播平台开始涌现,这火热的程度好像一个应用不带上直播业务出来都不好意思跟人打招呼.想要做一个直播业务,主要包括三 ...
- mxnet设置动态学习率(learning rate)
https://blog.csdn.net/xiaotao_1/article/details/78874336 如果learning rate很大,算法会在局部最优点附近来回跳动,不会收敛: 如果l ...