今天来补之前刷过的专题,查并集是一个比较简单的专题:查并集有三种类型,第一种类型是普通查并集,第二个就带权查并集 第三种就是种类查并集
第一种简单查并集主要就是那两个函数:
int find(int x)
{
return x == pre[x] ? x : find(pre[x]);
}
void join(int x, int y)
{
int root1, root2;
root1 = find(x);
root2 = find(y);
if(root1 != root2)
{
pre[root2] = root1;
}
}
通过找根节点是否相同,然后再进行合并树。查询他们是否相关的时候就是查询他们的根节点是否相等。
带权并查集:就是通过计算不同顶点到达根节点的距离,然后将他们的差%rand来判断两个顶点之间的关系,sum[i]数组就是计算顶点i到达根节点的距离。也可以直接取余rand 余数为0就是和根节点相同类型,余数为1就是根节点下一个类型,以此类推
每次查找根节点时候都要跟新一下sum数组因为合并两棵树的时候只跟新了父亲节点的sum,子节点没有跟新
合并的时候利用y,x的关系来确定fx,fy的关系,father[fy]=0,然后就可以求出sum[fx]
逻辑如图所示,曾经想过做这种题目有一种莽夫行为,就是有多少种类型就开多个并查集树。当fathet[i]=i时候就说明他没有插入过,就安排在下一个没有安排过的类中,这种行为比较恶习,判断语句实在太多,所以说他有点莽夫。