UVA11987 Almost Union-Find [带权并查集]
Almost Union-Find
题目描述

输入输出格式
输入格式:

输出格式:

输入输出样例
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
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 [带权并查集]的更多相关文章
- POJ 1703 Find them, Catch them(带权并查集)
传送门 Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42463 Accep ...
- hdu 1829-A Bug's LIfe(简单带权并查集)
题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...
- POJ 2912 Rochambeau(难,好题,枚举+带权并查集)
下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...
- POJ 1733 Parity game(离散化+带权并查集)
离散化+带权并查集 题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的. 思路:此题同HDU 3038 差不多,询问 ...
- codeforces 687D Dividing Kingdom II 带权并查集(dsu)
题意:给你m条边,每条边有一个权值,每次询问只保留编号l到r的边,让你把这个图分成两部分 一个方案的耗费是当前符合条件的边的最大权值(符合条件的边指两段点都在一个部分),问你如何分,可以让耗费最小 分 ...
- POJ2492 A Bug's Life 带权并查集
分析:所谓带权并查集,就是比朴素的并查集多了一个数组,记录一些东西,例如到根的距离,或者和根的关系等 这个题,权数组为relation 代表的关系 1 和父节点不同性别,0,和父节点同性别 并查集一 ...
- Zjnu Stadium(hdu3047带权并查集)
题意:一个300列的无限行的循环场地,a b d代表a,b顺时针相距d的距离,现在给你一些距离,判断是否有冲突,如果有冲突计算冲突的次数 思路:带权并查集 a,b的距离等于b到根节点的距离 - a到根 ...
- Exclusive-OR(带权并查集)
Exclusive-OR Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- POJ 1988 Cube Stacking 【带权并查集】
<题目链接> 题目大意: 有几个stack,初始里面有一个cube.支持两种操作: 1.move x y: 将x所在的stack移动到y所在stack的顶部. 2.count x:数在x所 ...
随机推荐
- 在vue中使用animate.css
animate.css是一款前端动画库,相似的有velocity-animate 用法: 首先 npm install animate.css --save 然后在vue文件的script中引入: i ...
- asp.net 遍历文件夹下全部子文件夹并绑定到gridview上
遍历文件夹下所有子文件夹,并且遍历配置文件某一节点中所有key,value并且绑定到GridView上 Helper app_Helper = new Helper(); DataSet ds = n ...
- flex实例(阮一峰)
Flex 布局教程:实例篇 作者: 阮一峰 日期: 2015年7月14日 上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法. 你会看到,不管是什么布局,Flex往往都可以几行命令 ...
- Python ctypes中cast/py_object用法
class ctypes.py_object Represents the C PyObject * datatype. Calling this without an argument create ...
- [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 ...
- python第三方库之numpy基础
前言 numpy是python的科学计算模块,底层实现用c代码,运算效率很高.numpy的核心是矩阵narray运算. narray介绍 矩阵拥有的属性 ndim属性:维度个数 shape属性:维度大 ...
- Vuex-Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation.Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 ...
- Java Tuple使用实例(转)
转自链接:http://www.cnblogs.com/davidwang456/p/4514659.html 一.为什么使用元组tuple? 元组和列表list一样,都可能用于数据存储,包含多个数据 ...
- 根据名字杀死进程Killall
Killall命令可以用来给一个特定的进程发送一个信号.这个信号默认情况下是SIGTERM,但也可以由killall命令使用参数来指定其它信号.现在让我们通过一些实际的例子来看看这个命令的实际用法. ...
- NOIP填坑计划
斗地主 华容道 开车旅行 疫情控制 飞扬的小鸟 Mayan游戏 天天爱跑步