uva 11987 带删除操作的并查集与并查集的可持久化
2015-08-23 16:50
429 查看
难点在于操作2,对于叶子结点而言,删除是很简单的,而对于根节点,删除好像是“不可能的”,所以我们可以在初始化的时候动一些脑筋,让每个结点最开始的父亲不是自己而是一个”虚节点(i+n)“,这样所有的结点都变成了叶子结点,然后问题就变得容易解决了。
还有一种方法叫做”可持久化并查集“,随后补上。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; const int N = 200001; int f ; ll sum ; int num ; int n, m; void init() { for ( int i = 1; i <= n; i++ ) { f[i] = i + n; } for ( int i = n + 1; i <= 2 * n; i++ ) { f[i] = i; sum[i] = i - n; num[i] = 1; } } int findf( int x ) { if ( f[x] != x ) f[x] = findf( f[x] ); return f[x]; } void union_set( int x, int y ) { x = findf(x), y = findf(y); if ( x != y ) { f[x] = y; sum[y] += sum[x]; num[y] += num[x]; } } void move( int x, int y ) { int fx = findf(x), fy = findf(y); sum[fx] -= x; num[fx]--; f[x] = fy; sum[fy] += x; num[fy]++; } int main () { while ( scanf("%d%d", &n, &m) != EOF ) { init(); while ( m-- ) { int op, p, q; scanf("%d", &op); if ( op == 1 ) { scanf("%d%d", &p, &q); union_set( p, q ); } else if ( op == 2 ) { scanf("%d%d", &p, &q); move( p, q ); } else { scanf("%d", &p); p = findf(p); printf("%d %lld\n", num[p], sum[p]); } } } return 0; }
还有一种方法叫做”可持久化并查集“,随后补上。
相关文章推荐
- css图片文字相关属性
- RequestAnimationFrame
- Android(java)学习笔记190:Eclipse中的控制台不停报错Can't bind to local 8700 for debugger
- PHP到MySQL数据查询过程概述
- netty5学习笔记-内存泄露检测
- (3.1.2.2)有关Servlet初始化参数的获取方法
- HDU 1036.Average is not Fast Enough!【精度及格式控制】【8月23】
- 为什么人人都该懂点LLVM
- 在Word中用快捷键转换英文字母大小写
- 二叉树的那些事
- netty5学习笔记-内存泄露检测
- C++ STL vector(向量容器)的使用(附完整程序代码)
- Manaher算法总结
- JS的HTML DOM disabled 属性
- Double Shortest Paths(费用流)2014年省赛D题
- javascript 如何访问 action或者controller 传给 jsp 页面的值
- poj1273 最大流模板 Edmond_karp算法
- C++学习——vector
- 1-2、自定义Partitioner代码
- DP_ural_Metro