0
点赞
收藏
分享

微信扫一扫

并查集漫谈

心智的年轮 2022-04-30 阅读 49
算法c++

武林风云录

在王者大陆上,存在着很多派系,大家各自有各自的领袖。不同门派的帅小伙没什么正经工作,在峡谷里面溜达,见面以后往往会在物理上打成一片,但是由于派系里面都是体面人,大家不会打朋友的朋友,而且大家都只知道自己的直接上级。比如木兰和凯的关系比较好,拉拢一伙人自成了一派,号称长城守卫军,有一天盾山看到了凯,由于互相不熟,两个就想比划比划,但是打之前,他们会先确定一下各自是否在一个派系,盾山问了一下上级守约,守约说自己的上级是花木兰且木兰没有上级了,盾山报出自己的最终上级是木兰,凯也报出来自己的上级是木兰。哎呀,原来是寄几人,失礼失礼。于是两个人收起了自己的家伙,一起双双把家还了。

请添加图片描述

不难看出,在上面的过程中,整个长城守卫军的结构可以看作是一个树形结构,每个成员与自己的直接上级相连,但是可以沿着关系找到最终上级。而如果双方的最终上级不一致的话会是什么请况呢,比较明显的是,这将是一个拥有多个连通分量的图。其中包括长城守卫军、稷下学院和魏蜀吴等阵营,他们共同组成了现在的王者关系图。对于不同阵营的两位帅小伙,我们更希望的是他们能够和谐相处,最直接的方式就是让其中某一个阵营的领袖加入另外一个阵营,比如曹老板好人妻,所以占了木兰,木兰的上级改成曹操,最后长城守卫军的成员和魏地帅小伙见面就和谐相处了,因为他们拥有相同的领袖—曹老板。当然这里合并的话,谁合并谁都没区别,效果相同,至少目前来说如此

请添加图片描述

上面的过程中有两个比较重要的过程,一个是找上级的过程,一个是合并阵营的过程,这两个过程提取出一个词叫做并查集。并查集解决的问题就是这类关系套关系的问题。

那么下面的问题就是,怎么实现上面的过程呢。首先是直接上级,可以采用数组faction[maxN]来存储,具体体现为,faction[i]=x代表的意思就是i的直接上级是x,如果要查找到派系领袖,也就是最终上级,只需要加上一个简单的循环。

int faction[1005]; //描述节点之间派系的数组

//查找节点的祖先
int findAncestor(int x) {
    while(faction[x] != x) { //查找X的最终上级
        x = faction[x];
    }
    
    return x;
}

好了,查找的过程就解决了,那么合并阵营呢?其实这里更简单,直接找到两位帅小伙x、y的阵营领袖,分别是rootx、rooty。现在的话faction[rootx]==rooty直接就能实现效果,此后原先x阵营的兄弟们的直接上级就变成了rooty,完整的合并函数如下。

//合并两个节点的派系
void unionFaction(int x, int y) {
    int aneX = findAncestor(x);
    int aneY = findAncestor(y);
    //合并之
    faction[aneX] = aneY; 
}

是不是炒鸡简单!

举报

相关推荐

0 条评论