UnionFind(PYthon实现)

UnionFind用于解决图的连通性问题,不需要给出具体路径的情况,可用来计算连通分支数

参考链接:

这两篇博客对于问题讲的非常好,本文只给出Python的实现代码,以供参考

class Quick_Find:
    def __init__(self,N):
        self.count = N
        self.ids = [i for i in range(self.count)]

    def connect(self,p,q):
        return self.find[p] == self.find(q)

    def find(self,p):
        return self.ids[p]

    def union(self,p,q):
        pId = self.find(p)
        qId = self.find(q)

        if pId == qId:
            return

        for i in range(len(self.ids)):
            if self.ids[i] == pId:
                self.ids[i] = qId
        self.count-=1

    def getcount(self):
        return self.count



class Quick_Union:

    def __init__(self,N):
        self.count = N
        self.ids = [i for i in range(N)]

    def connect(self,p,q):
        return self.find(p) == self.find(q)

    def find(self,p):
        while self.ids[p] != p: # 循环,直到找到根节点
            p = self.ids[p]
        return p

    def union(self,p,q):
        pID = self.find(p)
        qID = self.find(q)
        if pID == qID:
            return
        self.ids[pID] = qID
        self.count -= 1

    def getcount(self):
        return self.count


class Weighted_Union_Find:
    def __init__(self,N):
        self.count = N
        self.ids = [i for i in range(N)]
        self.size = [1 for i in range(N)] # 加权

    def connect(self,p,q):
        return self.find(p) == self.find(q)

    def find(self,p):
        while self.ids[p] != p:
            p = self.ids[p]
        return p

    def union(self,p,q):
        pID = self.find(p)
        qID = self.find(q)
        if pID == qID:
            return
        if self.size[pID] < self.size[qID]: # 小的树并到大的树下
            self.ids[pID] = qID
            self.size[qID] += self.size[pID]
        else:
            self.ids[qID] = pID
            self.size[pID] += self.size[qID]
        self.count-=1

    def getcount(self):
        return self.count

if __name__ == '__main__':
    N,M = list(map(int,input().split())) # N为节点数目 M为输入关系系的数目
    # uf = Quick_Find(N)
    # uf = Quick_Union(N)
    uf = Weighted_Union_Find(N)
    for i in range(M):
        p,q = list(map(int,input().split())) # p、q建立关系
        if not uf.connect(p,q): # 若还未连接
            uf.union(p,q)
    print(uf.getcount())
输入测试:
8 5
2 3
1 0
0 4
5 7
6 2
result:3
posted @ 2018-09-07 10:07  几度夏  Views(1180)  Comments(0Edit  收藏  举报