uva 11987 带删除的并查集
来源:互联网 发布:网络用语奶是什么意思 编辑:程序博客网 时间:2024/05/22 06:20
Initially, the collection contains n sets: {1}, {2}, {3}, … , {n}.
Input
There are several test cases. Each test case begins with a line containing two integers n and m
(1 ≤ n, m ≤ 100, 000), the number of integers, and the number of commands. Each of the next m lines
contains a command. For every operation, 1 ≤ p, q ≤ n. The input is terminated by end-of-file (EOF).
Output
For each type-3 command, output 2 integers: the number of elements and the sum of elements.
Explanation
Initially: {1}, {2}, {3}, {4}, {5}
Collection after operation 1 1 2: {1,2}, {3}, {4}, {5}
Collection after operation 2 3 4: {1,2}, {3,4}, {5} (we omit the empty set that is produced when
taking out 3 from {3})
Collection after operation 1 3 5: {1,2}, {3,4,5}
Collection after operation 2 4 1: {1,2,4}, {3,5}
输入 1 a b 把a,b所在的集合合并
输入 2 a b 把b从b所在的旧集合移到a的集合中
输入 3 a 输出a所在集合的元素个数和这个集合的元素和
一开始想并查集能做吗 怎么这么像stl 最后发现还是并查集
思路,如何删除一个并查集里面的一个元素加到另一个并查集内,通过思考发现,旧的并查集如果移除的是一般的结点还好做,如果是根节点,出现群龙无首的情况是不行的,所以旧的集合里面的根节点 f[根节点]是不能改变的。那么改变什么才好,- -答案就是用一个新的数组 po 反应的是当前元素的根节点的最新位置,即移除后的位置。 所有的find和merge都用id数组来寻找根结点,而f永远指向的是根节点,那么删除的话虽然元素和减少了但是对根节点的指向是不会变化的 因为f[ ]没变,再用po创建一个大于n的新空间放这个单独的元素就好。
由于求的东西比较多,指向当前位置的用 数组po 指定的是最新的位置。
用sum数组求根的里存放的和来代表集合的和
用pre数组代表集合里面的个数。
用f求的是父节点和根 每一个集合,即使删除也有旧的集合保留。父节点依旧保留
#include <iostream>#include <cstdio>#include <map>#include <cstring>using namespace std;const int maxn=100100;int f[maxn];int sum[maxn];int pre[maxn];int po[maxn];int n,m;int find(int x){ return (x==f[x])?f[x]:f[x]=find(f[x]);}int init(){ for(int i=1;i<=n;i++) { f[i]=i; sum[i]=i; po[i]=i; pre[i]=1; }}void merge(int a,int b){ int p=find(a); int q=find(b); if(p!=q) { f[p]=q; pre[q]+=pre[p]; sum[q]+=sum[p]; }}int main(){ while(cin>>n>>m) { init(); int yi=n; for(int i=0;i<m;i++) { int op; cin>>op; if(op==1) { int a,b; cin>>a>>b; merge(po[a],po[b]); } if(op==2) { int a,b; cin>>a>>b; int p1=find(po[a]); int p2=find(po[b]); if(p1!=p2) { int t=find(po[a]); sum[t]-=a; pre[t]--; po[a]=++yi; f[yi]=yi; pre[yi]=1; sum[yi]=a; merge(po[a],po[b]); } } if(op==3) { int a; cin>>a; int p1=find(po[a]); cout<<pre[p1]<<" "<<sum[p1]<<endl; } } }}
- uva 11987 带删除的并查集
- UVA 11987 Almost Union-Find (带权并查集的操作及并查集的删除操作)
- uva 11987 Almost Union-Find(带删除操作的并查集)
- uva 11987 Almost Union-Find(带删除操作的并查集)
- UVA - 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find(带删除操作的并查集)
- UVA - 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find(带删除的并查集)
- UVa-11987 Almost union-find(带删除操作的并查集)
- UVA11987 带删除的并查集
- UVA11987(带权并查集的删除操作)
- FZU - 2155 - 盟国 (带删除的并查集~~)
- vijos 幼儿园战争 带删除的并查集
- UVA 11987 Almost Union-Find 并查集节点删除
- 带权并查集--删除--UVA11987
- UVa 11987 Almost Union-Find (加权并查集&删除结点的技巧)
- UVA 11987 Almost Union-Find(带有删除操作的并查集)
- uva 11987 Almost Union-Find(并查集的删除操作)
- js中object类型中的三个方法
- 一文搞懂HMM(隐马尔可夫模型)
- 【JZOJ 3870】单词检索
- Android学习之模块化过程多渠道编译详解
- Dwr初认识
- uva 11987 带删除的并查集
- shell之输出重定向(理解2>&1)
- IO流_throws的方式处理异常
- 关于关系型数据库表的设计
- 设计模式之命令模式的作用
- HTTP状态码列表
- 注册表操作
- react-native(Fetch网络请求数据)
- Future 模式详解(并发使用)