並查集演算法應用

2021-10-01 21:18:18 字數 2288 閱讀 2310

並查集是一種樹型的資料結構,用於處理一些不相交集合(disjoint sets)的合併及查詢問題。常常在使用中以森林來表示。

並查集也被稱為不相交集資料結構。顧名思義,並查集主要操作是合併與查詢,它是把初始不相交的集合經過多次合併操作後合併為乙個大集合,然後可以通過查詢判斷兩個元素是否已經在同乙個集合中了。

在python中,並查集可以通過list或者dict等資料結構實現

547. 朋友圈

給定乙個 n * n 的矩陣 m,表示班級中學生之間的朋友關係。如果m[i][j] = 1,表示已知第 i 個和 j 個學生互為朋友關係,否則為不知道。你必須輸出所有學生中的已知的朋友圈總數。

並查集的主要方法有:查詢/連通/判斷是否連通

這道題的**相對較為簡單:

class solution:

def findcirclenum(self, m: list[list[int]]) -> int:

n = len(m)

p = [[i] for i in range(n)] #先生成並查集的節點

ans = n

for i in range(n):

for j in range(i):

if m[i][j] == 1 and p[i] is not p[j]: #如果i和j是好朋友,但p中沒有顯示則

p[i] += p[j] #在p[i]中加入p[j]

for k in p[j]: #對於p[j]中的每個數字,定義其根節點為p[i]

p[k] = p[i]

ans -= 1 #朋友圈的數量 - 1

print(p) #本題結果為[[1, 0], [1, 0], [2]]

return ans

在這道題目中傳統的方式可以將各個方法都實現出來,如下:

class solution(object):

def findcirclenum(self, m):

""":type m: list[list[int]]

:rtype: int

"""# 宣告表示集合的樹,用陣列表示樹,如 parent[5] == -1 表示

# 5 是某個集合的代表,同時也是樹根

parent = [-1] * len(m)

# 為各個集合的深度排個序

rank = dict()

# 只遍歷左下部分

for i in range(len(m)):

for j in range(i):

if m[i][j] == 1:

# 如果兩人是朋友,就把兩人放入同乙個集合

self.union(i, j, parent, rank)

ans = 0

print(parent)

for i in parent: # 檢視有多少集合,即多少個朋友圈

if i == -1:

ans += 1

return ans

def findroot(self, num, parent):

""":num:某個小朋友

:parent:多個集合樹

一直找到這個小朋友所在集合的代表,即樹根

"""while parent[num] != -1:

num = parent[num]

return num

def union(self, x, y, parent, rank):

"""x,y 表示滿足朋友關係的兩小朋友

"""if x == y: # 表示自己和自己是朋友,這個直接返回

return

x = self.findroot(x, parent) # 找到所在集合的代表,可能就是自己

print("x is",x)

y = self.findroot(y, parent)

print("y is",y)

rank_x = rank[x] if x in rank else 0 # 查詢該集合目前的深度

rank_y = rank[y] if y in rank else 0

if x == y: # 檢測到 x, y 已經是在同乙個集合了,直接返回

return

if rank_x > rank_y: # 這裡是做路徑壓縮的,避免樹太深使得 findroot 函式耗時過多

parent[y] = x

elif rank_x < rank_y:

parent[x] = y

else:

parent[x] = y

rank[y] = 1

並查集演算法

所謂並查集,它是乙個集合,這個集合的元素也是集合,他支援三種操作 makeset x 建立乙個只有乙個元素x的集合x0,將這個集合放入並查集中 findset x 在並查集中尋找乙個元素s 注意並查集的元素s也是集合 滿足 x屬於s union x,y 將並查集中的元素s1,s2合併,其中x屬於s1...

並查集演算法

並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。1 makeset s 建立乙個新的並查集,包含s個單元素集合。2 union x,y 把x ...

並查集演算法

includeint pre 10 int find int x 查詢祖先節點 int i x,j while i r 壓縮路徑 return r void join int x,int y int main 2 食物鏈問題 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈...