啊哈算法--并查集 (python) - Go语言中文社区

啊哈算法--并查集 (python)


 并查集算法是通过一个一维数组来实现的,其本质是维护一个森林。

初始化

刚开始的时候,森林的每个点都是孤立的,也可以理解为一颗只有一个结点的树,也就是说每个结点的父结点都是它本身。

# 这是初始化函数
def init():
    global n
    for i in range(1,n+1):
        f[i] = i
    return

找爹函数

可以使用递归函数来进行寻找父结点,在找父结点的过程中将过程中的结点指向父结点。这也被称为“擒贼先擒王”原则、

# 这是找父节点的递归函数
def getf(v):
    if f[v] == v:
        return v
    else:
        # 这里是路径压缩,每次在函数返回的时候顺便把论述遇到的人的‘boss’
        # 改为最后找到的祖宗编号,这样可以提高今后找到犯罪团伙的最高领导人的速度
        f[v] = getf(f[v])
        return f[v]

合并结点

合并的过程其实是“认爹”的过程,在该过程中要遵循“靠左”原则和“擒贼先擒王”原则。

# 这是两个子集合并的函数
def merge(v, u):
    t1 = getf(v)
    t2 = getf(u)
    if t1 != t2:
        f[t2] = t1 # 这里使用靠左原则,即把右边的集合作为左边集合的子集
    return

完整代码如下

n, sum = 0, 0
f = [0 for i in range(1000)]
# 这是初始化函数
def init():
    global n
    for i in range(1,n+1):
        f[i] = i
    return
# 这是找父节点的递归函数
def getf(v):
    if f[v] == v:
        return v
    else:
        # 这里是路径压缩,每次在函数返回的时候顺便把论述遇到的人的‘boss’
        # 改为最后找到的祖宗编号,这样可以提高今后找到犯罪团伙的最高领导人的速度
        f[v] = getf(f[v])
        return f[v]
# 这是两个子集合并的函数
def merge(v, u):
    t1 = getf(v)
    t2 = getf(u)
    if t1 != t2:
        f[t2] = t1 # 这里使用靠左原则,即把右边的集合作为左边集合的子集
    return

if __name__ == '__main__':
    # print("test")
    n, m = map(int,input().split())
    init()
    # 合并团伙
    for i in range(1,m+1):
        x,y = map(int,input().split())
        merge(x,y)
    # 寻找独立的团伙
    for i in range(1,n+1):
        print(f[i], end = ' ')
        if f[i] == i:
            sum += 1
    print()
    print(sum)

'''
测试样例
10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4
'''

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_43211230/article/details/125435016
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-03 16:13:32
  • 阅读 ( 227 )
  • 分类:算法

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢