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

这道题最难的地方就是操作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. 030、Java中的求模计算

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  2. 安卓多个按钮使用一个OnClickListener

    安卓studio 3.1 版本编译通过 一个按钮id为bt1 一个按钮Id为bt2 mainactivity 代码入下 package com.example.vmpdump.firstapp; im ...

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

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

  4. 剑指offer自学系列(四)

    题目描述: 输入一个正整数数组,把数组里面所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个,例如输入数组{3,32,321},输出的最小数字为321323 题目分析: 如果采用穷举法,把 ...

  5. HihoCoder第八周:状态压缩 一

    1044 : 状态压缩•一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前 ...

  6. C++面试常见问题——02动态分配内存

    动态分配内存 C++动态内存 C++程序中内存分为两个部分 堆:程序中未使用的内存,在程序运行时可用于动态分配内存. 栈:函数内部申明的所有变量都将占用栈内存. 很多时候不知道一个程序到底需要多少内存 ...

  7. 在远程服务器上执行本地的shell脚本

    在远程服务器上执行本地的shell脚本 [root@localhost zzx]# sh echoip.sh 192.168.67.131[root@localhost zzx]# ssh root@ ...

  8. JavaScript原生Ajax请求纯文本数据

    源代码 ajax1.html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  9. cf754 754D - Fedor and coupons

    2个多小时,弱智了..(连A都做不对,就不要做D了(迷)) #include<bits/stdc++.h> #define lowbit(x) x&(-x) #define LL ...

  10. PlayJava SpringMVC与Struts2杂谈

    一 先做一个简单对比: 1. SpringMVC的入口是Servlet,核心是DispatcherServlet,Struts2是Filter,核心是FilterDispatcher 2. Sprin ...