并查集模板
2013-07-20 23:11
169 查看
普通并查集:
带路径压缩的的findset函数:
1.while版本
2.递归版本
个人经验表明在递归版本不栈溢出的情况下,递归版本和循环版本的效率并没有太大差别,并且对于带路径压缩的并查集,基本上不会发生“递归栈溢出”。
另外,union_nodes函数还可以可以采用启发式合并,思路就是把深度较小的那棵子树并到深度较大的那棵子树上,不过一般情况下路径压缩就够用了。
听人说并查集还可以“离散化”,个人从字面上理解应该是指用map、hash来保存每个节点,从而当节点分布比较稀疏的时候,可以比普通并查集更快的完成初始化等工作(待商榷)。
#define MAX_SIZE 100005 int pa[MAX_SIZE]; //存储有向图的边 void init() //初始化 该函数可以根据具体情况保存和初始化需要的内容 { for(int i = 0; i < MAX_SIZE; i++) { pa[i] = i; } } int findset(int a) //不带路劲压缩 { while(pa[a] != a) { a = pa[a]; } return a; } void union_nodes(int a, int b) //集合合并 { int a1 = findset(a); int b1 = findset(b); if(a1 != b1) //这个判定条件可选,主要是为了防止findset路径压缩的时候出现死循环 { pa[a1] = b1; //如果存的是有向图,并且做题时集合中元素的顺序很重要,不能忽略,那么这里应该用"pa[a] = b;" } }
带路径压缩的的findset函数:
1.while版本
int findset(int v) //找元素所在集合的代表元(因为用了路径压缩,路径压缩的主要目的是为了尽快的确定元素所在的集合) { int t1,t2=v; while(v!=pa[v]) v=pa[v]; while(t2!=pa[t2]) //这里优化的思路还是路径压缩(进一步的在查找函数执行的过程中压缩路径),很神奇! { t1=pa[t2]; pa[t2]=v; t2=t1; } return v; }
2.递归版本
int findset(int x) { if(pa[x] != x) { int root = findset(pa[x]); return pa[x] = root; } else { return x; } }
个人经验表明在递归版本不栈溢出的情况下,递归版本和循环版本的效率并没有太大差别,并且对于带路径压缩的并查集,基本上不会发生“递归栈溢出”。
另外,union_nodes函数还可以可以采用启发式合并,思路就是把深度较小的那棵子树并到深度较大的那棵子树上,不过一般情况下路径压缩就够用了。
听人说并查集还可以“离散化”,个人从字面上理解应该是指用map、hash来保存每个节点,从而当节点分布比较稀疏的时候,可以比普通并查集更快的完成初始化等工作(待商榷)。
相关文章推荐
- 并查集(——模板习题与总结)
- [备战NOI同步赛]适合ACM-ICPC的并查集模板
- 【bzoj1455】【罗马游戏】左偏树+并查集(模板)
- hdu1213并查集模板
- 并查集模板。。。。
- HDU 1213 How Many Tables(并查集模板)
- 【20171108】Luogu P3367 模板题:并查集
- HDU 1213 How Many Tables(模板——并查集)
- POJ 2524 宗教信仰 并查集 基础模板
- 并查集模板题 HDU1856 More is better
- 【模板】并查集
- 普通并查集模板
- 【并查集模板】并查集模板 luogu-3367
- HDU 1856 More is better(简单并查集) 【最大并查集人数模板】
- hdu1213(并查集模板)
- POJ - 2236 Wireless Network (并查集+自用模板v1.2)
- 模板:并查集
- HDU 1232 畅通工程 【并查集模板】
- hdu 1863(畅通工程)(简单的并查集,模板)
- 并查集模板