在kurskal算法中运用Disjoint Set/Union-find Sets/并查集

  1. Disjoint Set/Union-find Sets/并查集 的概念
    https://algorithms.tutorialhorizon.com/disjoint-set-union-find-algorithm-union-by-rank-and-path-compression/
    https://www.cnblogs.com/shadowwalker9/p/5999029.html

MakeSet/初始化树
The MakeSet operation makes a new set by creating a new element with a unique id, a rank of 0, and a parent pointer to itself. The parent pointer to itself indicates that the element is the representative member of its own set.
函数MakeSet 对所有元素创造全为0的rank矩阵,以及指向自己的parent矩阵。指向自己表明元素的代表是它们自己。

The MakeSet operation has O(1) time complexity.
函数MakeSet复杂度为O(1)

function MakeSet(x)
   if x is not already present:
     add x to the disjoint-set tree
     x.parent := x
     x.rank   := 0

如果合并两个集合
最差情况复杂度O(LogN)
Pseudo Code:

function Union(x, y)
   xRoot := Find(x)
   yRoot := Find(y)
 
   // x and y are already in the same set
   if xRoot == yRoot            
       return
   
   // x and y are not in same set, so we merge them
    if xRoot.rank < yRoot.rank 
      xRoot.parent := yRoot 
    else if xRoot.rank > yRoot.rank
      yRoot.parent := xRoot
   else
     xRoot.parent := yRoot
     yRoot.rank   := yRoot.rank + 1

路径压缩Path compression

function Find(x)
   if x.parent != x
     x.parent := Find(x.parent)
   return x.parent
  1. kruskal
# Python program for Kruskal's algorithm to find 
# Minimum Spanning Tree of a given connected, 
# undirected and weighted graph 

from collections import defaultdict 

#Class to represent a graph 
class Graph: 

	def __init__(self,vertices): 
		self.V= vertices #No. of vertices 
		self.graph = [] # default dictionary 
								# to store graph 


	# function to add an edge to graph 
	def addEdge(self,u,v,w): 
		self.graph.append([u,v,w])  #The append() method adds an item to the end of the list.

	# A utility function to find set of an element i 
	# (uses path compression technique) 
	def find(self, parent, i): 
		if parent[i] == i: 
			return i 
		return self.find(parent, parent[i]) 

	# A function that does union of two sets of x and y 
	# (uses union by rank) 
	def union(self, parent, rank, x, y): 
		xroot = self.find(parent, x) 
		yroot = self.find(parent, y) 

		# Attach smaller rank tree under root of 
		# high rank tree (Union by Rank) 
		if rank[xroot] < rank[yroot]: 
			parent[xroot] = yroot 
		elif rank[xroot] > rank[yroot]: 
			parent[yroot] = xroot 

		# If ranks are same, then make one as root 
		# and increment its rank by one 
		else : 
			parent[yroot] = xroot 
			rank[xroot] += 1
			print ("if x != y而且xroot=",xroot,"yroot=",yroot,"rank相同, 把parent[y的parent] 替换为 x的parent,","rank是",rank,'\n')
	# The main function to construct MST using Kruskal's 
		# algorithm 
	def KruskalMST(self): 

		result =[] #This will store the resultant MST 

		i = 0 # An index variable, used for sorted edges 
		e = 0 # An index variable, used for result[] 

			# Step 1: Sort all the edges in non-decreasing 
				# order of their 
				# weight. If we are not allowed to change the 
				# given graph, we can create a copy of graph 
		self.graph = sorted(self.graph,key=lambda item: item[2]) 
		print ("self.graph是",self.graph,'\n')

		parent = [] ; rank = [] 

		# Create V subsets with single elements 
        # this is MakeSet(X)
		for node in range(self.V): 
			parent.append(node)     #parent is [0, 1, 2, 3]
			rank.append(0)          #rank is [0, 0, 0, 0]
		# Number of edges to be taken is equal to V-1 
		while e < self.V -1 : 

			# Step 2: Pick the smallest edge and increment 
					# the index for next iteration 
            # for each e th, pick up one acceptable edge         
			u,v,w = self.graph[i] 
            # for each i th, pick up one possible edge   
			i = i + 1
			x = self.find(parent, u) 
			y = self.find(parent ,v)
			print ("当e=",e,"时","i=",i-1,"时",'\n')
			print ("x是",x,'\n',"y是",y,'\n')
			# If including this edge does't cause cycle, 
						# include it in result and increment the index 
						# of result for next edge 
            # 如果u的parent=v的parent,说明成环            
			if x != y: 
				e = e + 1	
				result.append([u,v,w]) 
				self.union(parent, rank, x, y)			 
				print ("if x != y,","parent是",parent,'\n')
            # Else discard the edge 

		# print the contents of result[] to display the built MST 
		print ("Following are the edges in the constructed MST")
		for u,v,weight in result: 
			#print str(u) + " -- " + str(v) + " == " + str(weight) 
			print ("%d -- %d == %d" % (u,v,weight)) 

# Driver code 
g = Graph(4)          #input sum. of vertices
g.addEdge(0, 1, 10)   #input edges and weight
g.addEdge(0, 2, 6) 
g.addEdge(0, 3, 5) 
g.addEdge(1, 3, 15) 
g.addEdge(2, 3, 4) 

g.KruskalMST() 

#This code is contributed by Neelam Yadav 

Result:
self.graph是 [[2, 3, 4], [0, 3, 5], [0, 2, 6], [0, 1, 10], [1, 3, 15]]

当e= 0 时 i= 0 时

x是 2
y是 3

if x != y而且xroot= 2 yroot= 3 rank相同, 把parent[y的parent] 替换为 x的parent, rank是 [0, 0, 1, 0]

if x != y, parent是 [0, 1, 2, 2]

当e= 1 时 i= 1 时

x是 0
y是 2

if x != y, parent是 [2, 1, 2, 2]

当e= 2 时 i= 2 时

x是 2
y是 2

当e= 2 时 i= 3 时

x是 2
y是 1

if x != y, parent是 [2, 2, 2, 2]

Following are the edges in the constructed MST
2 – 3 == 4
0 – 3 == 5
0 – 1 == 10

分析:
当e= 0 时 i= 0 时, 加入edge[0], 选取no.2做root,parent[3]变成2
当e= 1 时 i= 1 时, 加入edge[1],parent[0]变成2
当e= 2 时 i= 2 时, 发现edge[2]的两个verticles 2 和0 的parent都是2,说明成环,丢弃
当e= 2 时 i= 3 时, 加入edge[3],parent[0]变成2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值