zoukankan      html  css  js  c++  java
  • 并查集算法

    并查集算法

    描述

    对于给定的点,和点连接成的边,判断是否存在环。比如下图是存在。

    推导

    • 如果给定了边(0,1),(2,3),(3,4),(1,2),将这些点加入到一个set中[0,1,2,3,4],则在这个集合中任意取非边两点都会形成一个环。

    如图,如果有任意边(0,1),(3,4),(2,1),可以得到以下图

    又给定边(3,1)这条边的两个节点位于已知图上,如果直接用3连到1,会使一个节点有两个父节点,出现了断层,即无法判断层级关系,如果用1连到3,会使路径过长。正确的做法应该用他们的父节点相连。不考虑压缩路径的情况下,1连4或4连一都可以。

    思考:为什么要连3,1?

    • 将它和集合联系起来,java中set是用树来实现的,集合必定有且只有一个根节点,如果是根据形成环的定理来判断,要将这些点都要归为一个树结构。

    这样若给定边如(2,4),他们的跟节点都是1,所以是集合内的,必定会形成环。给定(2,5),无公共根节点,所以不会形成环,但是如果再给定(5,4),根节点都是1,会形成环。

    代码实现

    设定一个列表,列表的索引表示当前节点,索引对应的值代表父节点。

    • 为什么要压缩路径

      union_func方法中,如果直接parent[x_root] = y_root,最差情况会按链表的顺序来合并,比如,(0,1),(1,2),,,(999,1000),这样会有1000层查找即空间复杂度为On。压缩路径的话,如果是顺序节点的话,不会向下发展数的高度,只会多生长叶子结点,使得时间复杂度为O1。

    # 顶点数
    vertices = 6
    # 所有点设为-1
    parent = [-1] * vertices
    # rank代表层级
    rank = [0] * vertices
    
    
    # 寻找根节点:列表中的元素值是父节点的索引
    def find_root(x: int, li: list):
        x_root = x
        while li[x_root] != -1:
            x_root = li[x_root]
        return x_root
    
    
    # 合并 返回1合并成功 返回0合并失败
    def union_func(x: int, y: int, li: list, rank: list):
        x_root = find_root(x, li)
        y_root = find_root(y, li)
    
        if x_root == y_root:
            return 0
        else:
            # parent[x_root] = y_root
            # 压缩路径
            if rank[x_root] > rank[y_root]:
                parent[y_root] = x_root
            elif rank[y_root] > rank[x_root]:
                parent[x_root] = y_root
            else:
                parent[y_root] = x_root
                rank[x_root] += 1
    
            return 1
    
    
    def main():
        edges = [
            [0, 1], [1, 2], [1, 3],
            [2, 4], [3, 4], [2, 5]
        ]
    
        for i in range(len(edges)):
            x = edges[i][0]
            y = edges[i][1]
            if union_func(x, y, parent,rank) == 0:
                print("cycle detected")
                return
        print("no cycle")
        return
    
    
    if __name__ == '__main__':
        main()
    
    
  • 相关阅读:
    HUST 1372 marshmallow
    HUST 1371 Emergency relief
    CodeForces 629D Babaei and Birthday Cake
    CodeForces 629C Famil Door and Brackets
    ZOJ 3872 Beauty of Array
    ZOJ 3870 Team Formation
    HDU 5631 Rikka with Graph
    HDU 5630 Rikka with Chess
    CodeForces 626D Jerry's Protest
    【POJ 1964】 City Game
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/13737474.html
Copyright © 2011-2022 走看看