受教了,感谢玉斌大神的博客。

这道题最难的地方就是操作2,将一个集合中的一个点单独移到另一个集合,因为并查集的性质,如果该点本身作为root节点的话,怎么保证其他点不受影响。

玉斌大神的思路很厉害,受教受教,即,由于题目最终输出集合的元素个数与权值总和,故添加一个delete操作,将该点(设为P)所在集合的rank和sum值减小,将p的father引向一个从没定义过的点,(可以设置为(总数++)点),这样,虽然看似P还留在原集合,但仅仅作为一个空骨架,并不对集合的rank和sum产生影响。

具体实现,需要借助一个辅助数组 id[], id[]初始和father[]相同,但一旦需要删除操作,即将id[p]=++n,指向一个新位置,下次father[id[x]]即指向了新位置,跟原集合无关了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int father[]; //由于最坏可能有1000000次删除操作,故最大的数组量
int rank[];
long long sum[];
int id[];
int n;
int cnt;
void init()
{
for(int i=;i<=n;i++)
{
father[i]=i;
rank[i]=;
sum[i]=i;
id[i]=i;
}
cnt=n;
}
int findset(int x)
{
if (x!=father[x])
{
father[x]=findset(father[x]);
}
return father[x];
}
void unionset(int x,int y)
{
x=id[x];
y=id[y]; //所有点的指向,全部通过一个间接的id[x]的值来指向相应的值 即将所有点全部id化,不再已原来的本身值为id。
int r1=findset(x);
int r2=findset(y);
if (r1==r2) return;
if (rank[r1]>rank[r2])
{
father[r2]=r1;
rank[r1]+=rank[r2];
sum[r1]+=sum[r2];
}
else
{
father[r1]=r2;
rank[r2]+=rank[r1];
sum[r2]+=sum[r1];
}
}
void q1()
{
int p,q;
scanf("%d %d",&p,&q);
unionset(p,q);
}
void dele(int x)
{
int r=findset(id[x]);
rank[r]--;
sum[r]-=x;
id[x]=++cnt;
father[id[x]]=id[x];
rank[id[x]]=;
sum[id[x]]=x;
}
void q2()
{
int p,q;
scanf("%d %d",&p,&q);
int r1=findset(id[p]);
int r2=findset(id[q]);
if (r1==r2) return;
dele(p);
unionset(p,q);
}
void q3()
{
int p;
scanf("%d",&p);
int root=findset(id[p]);
printf("%d %lld\n",rank[root],sum[root]);
}
int main()
{
int q;
while (scanf("%d %d",&n,&q)!=EOF)
{
init();
int i,j,k;
for (i=;i<=q;i++)
{
int deno;
scanf("%d",&deno);
if (deno==) q1();
if (deno==) q2();
if (deno==) q3();
}
}
return ;
}

UVA 11987 - Almost Union-Find 并查集的活用 id化查找的更多相关文章

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

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

  2. UVA 572 油田连通块-并查集解决

    题意:8个方向如果能够连成一块就算是一个连通块,求一共有几个连通块. 分析:网上的题解一般都是dfs,但是今天发现并查集也可以解决,为了方便我自己理解大神的模板,便尝试解这道题目,没想到过了... # ...

  3. UVA 12232 - Exclusive-OR(带权并查集)

    UVA 12232 - Exclusive-OR 题目链接 题意:有n个数字.一開始值都不知道,每次给定一个操作,I a v表示确认a值为v,I a b v,表示确认a^b = v,Q k a1 a2 ...

  4. UVA 1160 - X-Plosives 即LA3644 并查集判断是否存在环

    X-Plosives A secret service developed a new kind ofexplosive that attain its volatile property only ...

  5. UVa 1455 Kingdom 线段树 并查集

    题意: 平面上有\(n\)个点,有一种操作和一种查询: \(road \, A \, B\):在\(a\),\(b\)两点之间加一条边 \(line C\):询问直线\(y=C\)经过的连通分量的个数 ...

  6. uva 1493 - Draw a Mess(并查集)

    题目链接:uva 1493 - Draw a Mess 题目大意:给定一个矩形范围,有四种上色方式,后面上色回将前面的颜色覆盖,最后问9种颜色各占多少的区域. 解题思路:用并查集维护每一个位置相应下一 ...

  7. UVA - 1160(简单建模+并查集)

    A secret service developed a new kind of explosive that attain its volatile property only when a spe ...

  8. UVA 1493 Draw a Mess(并查集+set)

    这题我一直觉得使用了set这个大杀器就可以很快的过了,但是网上居然有更好的解法,orz... 题意:给你一个最大200行50000列的墙,初始化上面没有颜色,接着在上面可能涂四种类型的形状(填充):  ...

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

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

随机推荐

  1. mysql limit查询入门

  2. 树莓派 Raspberry 软件源更改 看门狗启用

    看门狗无法在pi1上执行,似乎后更高级的pi上面才可用 1.替换脚本 下面脚本请直接复制到终端执行!! 适用于raspbian-stretch(基于Debian9) sudo -s echo -e & ...

  3. 反射①:如何获取class对象六种方法

    获取class对象的六种方法 了解:class类——是Java反射机制的入口,封装了一个类或接口的运行信息,通过调用Class类的方法可以获取这些信息,其特点如下: 1.该类在java.lang包中: ...

  4. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-step-forward

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  5. Eclipse新建Maven中创建src文件夹报The folder is already a source folder错误解决办法

    问题: 解决办法:右击项目->Build Path->Configure Build Path选择(missing)文件夹remove,然后重新New Source Folder

  6. flask部署:Ubuntu下使用nginx+uwsgi+supervisor部署flask应用

    之前一直用的Centos或者Red hat,自从使用Ubuntu后,发现Ubuntu使用起来更方便,自此爱上Ubuntu. 一.从github上下载flask应用 1.我已经成功将自己编写好的应用上传 ...

  7. Easy_vb

    拿到之后运行一下 之后使用ida打开先关键字搜索一下,结果就出来了

  8. [LeetCode] 927. Three Equal Parts 三个相等的部分

    Given an array A of 0s and 1s, divide the array into 3 non-empty parts such that all of these parts ...

  9. 从零开始学C++(0 简介)

    2020年,给自己定一个新目标————开始写技术博客,将之前所学的内容重新复习并整理成一系列的文章,一来可以让自己对这些基础知识更加熟悉,二来方便于以后的复习查阅. 以前自己都是以笔记的形式将知识点记 ...

  10. SPOJ DQUERY D-query 离线+树状数组

    本来是想找个主席树的题目来练一下的,这个题目虽说可以用主席树做,但是用这个方法感觉更加叼炸天 第一次做这种离线方法,所谓离线,就在把所有询问先存贮起来,预处理之后再一个一个操作 像这个题目,每个操作要 ...