并查集是一种可以在较短的时间内进行集合的查找与合并的树形数据结构
每次合并只需将两棵树的根合并即可
通过路径压缩减小每颗树的深度可以使查找祖先的速度加快不少
代码如下:
int getfather(int x) //查找祖先 { if(father[x]!=x) father[x]=getfather(father[x]); //路径压缩,把每个节点的父亲都变得与他的祖先相同 else return x; return father[x]; } int issame(int x,int y) //是否在同一个集合 { return getfather(x)==getfather(y); } void set_union(int x,int y) //合并 { int fx,fy; fx=getfather(x); fy=getfather(y); father[fx]=fy; }
并查集优化克鲁斯卡尔算法:
for(i=1;i<=n;i++) father[i]=i; qsort(e,k,sizeof(ed),cmp); ans=0; for(i=0;i<k;i++) { if(issame(e[i].l,e[i].r)) //跳过已在生成树中的边 continue; ans+=e[i].weight; set_union(e[i].l,e[i].r); }