洛谷传送门

Almost Union-Find

题目描述

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1:

5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
输出样例#1:

3 12
3 7
2 8

  分析:

  不得不说是一道神奇的题目

  如果只有操作1和操作3,那就是一道普通的带权并查集。然而,TM还有个毁天灭地的操作2。。。因为并查集是不支持删除操作的,所以我们得想个办法表示某一个元素在该集合中被删除。

  这里我们用一个数组$id[i]$记录$i$节点当前的编号,如果我们删除了一个点,我们就把$id[i]$指向一个新的地址,在原本的集合中删除掉它的信息,然后把这个新的地址与要合并的集合合并。原本的点就基本可以当作是“被废弃了”,因为我们每次查找一个点的集合的时候就直接$find(id[x])$。当然,$id[x]$一开始就赋值为$x$。

  不过貌似有巨佬用可持久化并查集$A$了,并不知道怎么用可持久化并查集做。。。。。。

  $PS$:写了个启发式合并,读优输优,水了个最优解$hahahaha$。

  Code:

  

//It is made by HolseLee on 22nd Aug 2018
//UVA11987
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std; typedef long long ll;
const int N=2e5+;
int n,m,id[N],fa[N],cnt[N],rk[N];
ll sum[N]; inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
} inline void print(int x)
{
if(x>)print(x/);
putchar(x%+'');
} inline int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
} inline void merge(int x,int y)
{
int fx=find(id[x]),fy=find(id[y]);
if(rk[fx]>rk[fy]){
fa[fy]=fx;
sum[fx]+=sum[fy];
cnt[fx]+=cnt[fy];
}else{
fa[fx]=fy;
sum[fy]+=sum[fx];
cnt[fy]+=cnt[fx];
if(rk[fx]==rk[fy])rk[fy]++;
}
} inline void del(int x)
{
int fx=find(id[x]);
cnt[fx]--;sum[fx]-=(ll)x;
id[x]=++n;
fa[id[x]]=id[x];
cnt[id[x]]=rk[id[x]]=;
sum[id[x]]=(ll)x;
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=n;++i)fa[i]=id[i]=i,sum[i]=(ll)i,cnt[i]=rk[i]=;
int op,x,y;
for(int i=;i<=m;++i){
op=read();
switch(op){
case :
x=read();y=read();
if(find(id[x])!=find(id[y]))merge(x,y);
break;
case :
x=read();y=read();
if(find(id[x])!=find(id[y])){
del(x);merge(x,y);
}
break;
case :
x=read();
print(cnt[find(id[x])]);
putchar(' ');
print(sum[find(id[x])]);
putchar('\n');
break;
}
}
}
return ;
}

UVA11987 Almost Union-Find [带权并查集]的更多相关文章

  1. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  2. hdu 1829-A Bug's LIfe(简单带权并查集)

    题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...

  3. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)

    下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...

  4. POJ 1733 Parity game(离散化+带权并查集)

    离散化+带权并查集 题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的. 思路:此题同HDU 3038 差不多,询问 ...

  5. codeforces 687D Dividing Kingdom II 带权并查集(dsu)

    题意:给你m条边,每条边有一个权值,每次询问只保留编号l到r的边,让你把这个图分成两部分 一个方案的耗费是当前符合条件的边的最大权值(符合条件的边指两段点都在一个部分),问你如何分,可以让耗费最小 分 ...

  6. POJ2492 A Bug's Life 带权并查集

    分析:所谓带权并查集,就是比朴素的并查集多了一个数组,记录一些东西,例如到根的距离,或者和根的关系等 这个题,权数组为relation 代表的关系  1 和父节点不同性别,0,和父节点同性别 并查集一 ...

  7. Zjnu Stadium(hdu3047带权并查集)

    题意:一个300列的无限行的循环场地,a b d代表a,b顺时针相距d的距离,现在给你一些距离,判断是否有冲突,如果有冲突计算冲突的次数 思路:带权并查集 a,b的距离等于b到根节点的距离 - a到根 ...

  8. Exclusive-OR(带权并查集)

    Exclusive-OR Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. POJ 1988 Cube Stacking 【带权并查集】

    <题目链接> 题目大意: 有几个stack,初始里面有一个cube.支持两种操作: 1.move x y: 将x所在的stack移动到y所在stack的顶部. 2.count x:数在x所 ...

随机推荐

  1. 在vue中使用animate.css

    animate.css是一款前端动画库,相似的有velocity-animate 用法: 首先 npm install animate.css --save 然后在vue文件的script中引入: i ...

  2. asp.net 遍历文件夹下全部子文件夹并绑定到gridview上

    遍历文件夹下所有子文件夹,并且遍历配置文件某一节点中所有key,value并且绑定到GridView上 Helper app_Helper = new Helper(); DataSet ds = n ...

  3. flex实例(阮一峰)

    Flex 布局教程:实例篇   作者: 阮一峰 日期: 2015年7月14日 上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法. 你会看到,不管是什么布局,Flex往往都可以几行命令 ...

  4. Python ctypes中cast/py_object用法

    class ctypes.py_object Represents the C PyObject * datatype. Calling this without an argument create ...

  5. [LeetCode] Intersection of Two Linked Lists 两链表是否相交

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  6. python第三方库之numpy基础

    前言 numpy是python的科学计算模块,底层实现用c代码,运算效率很高.numpy的核心是矩阵narray运算. narray介绍 矩阵拥有的属性 ndim属性:维度个数 shape属性:维度大 ...

  7. Vuex-Mutation

    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation.Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 ...

  8. Java Tuple使用实例(转)

    转自链接:http://www.cnblogs.com/davidwang456/p/4514659.html 一.为什么使用元组tuple? 元组和列表list一样,都可能用于数据存储,包含多个数据 ...

  9. 根据名字杀死进程Killall

    Killall命令可以用来给一个特定的进程发送一个信号.这个信号默认情况下是SIGTERM,但也可以由killall命令使用参数来指定其它信号.现在让我们通过一些实际的例子来看看这个命令的实际用法. ...

  10. NOIP填坑计划

    斗地主 华容道 开车旅行 疫情控制 飞扬的小鸟 Mayan游戏 天天爱跑步