UVA11987Almost Union-Find(并查集删除节点)
Posted zhaop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA11987Almost Union-Find(并查集删除节点)相关的知识,希望对你有一定的参考价值。
题意:n个数(即1-n)和m个操作:
1表示把x和y合并,2表示把x移到y集合里面,3表示统计x集合的元素个数
1,3好说,关键是2操作,可以先把2删除掉,删除的操作可以找一个其他的数字来取代x,这样就有新生出来一个集合,移到y集合就合并
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 100000; typedef long long LL; int father[N + N + 10]; int sum[N + N + 10],cnt[N + N + 10]; // sum求集合里面所有元素和,cnt表示个数 int value[N + N + 10]; //表示第i个数值 int n,m,k; void init() { k = n + 1; for(int i = 0; i <= n; i++) { father[i] = i; sum[i] = i; cnt[i] = 1; value[i] = i; } } int Find(int x) { if(x == father[x]) return x; return father[x] = Find(father[x]); } void Union(int x, int y) { int fx = Find(x); int fy = Find(y); if(fx != fy) { father[fx] = fy; sum[fy] += sum[fx]; cnt[fy] += cnt[fx]; } } void Remove(int x) { /* int fx = Find(value[x]); cnt[fx]--; sum[fx] -= x; value[x] = k; int fy = Find(value[y]); father[k] = fy; cnt[fy]++; sum[fy] += x; k++; */ int fx = Find(value[x]); cnt[fx]--; // 删除x时从父节点集合中减一 sum[fx] -= x; // sum中减去x value[x] = k; // 用 k 来代替 x ,生成了一个单独的集合,父节点是k cnt[k] = 1; sum[k] = x; father[k] = k; k++; } int main() { while(scanf("%d%d", &n, &m) != EOF) { k = n + 1; for(int i = 0; i <= n; i++) { father[i] = i; sum[i] = i; cnt[i] = 1; value[i] = i; } int order,p,q; while(m--) { scanf("%d", &order); if(order == 1) { scanf("%d%d", &p, &q); Union(value[p], value[q]); } else if(order == 2) { scanf("%d%d", &p, &q); int fx = Find(value[p]); int fy = Find(value[q]); if(fx != fy) // 如果p和q本来就在一个集合,就不用操作了。但是少了这个就wa了,不明白为什么操作不行 { Remove(p); Union(value[p], value[q]); } } else if(order == 3) { scanf("%d", &p); int fx = Find(value[p]); printf("%d %d\n", cnt[fx], sum[fx]); } } } return 0; }
以上是关于UVA11987Almost Union-Find(并查集删除节点)的主要内容,如果未能解决你的问题,请参考以下文章
UVa 11987 Almost Union-Find(支持删除操作的并查集)