#File Name : 最小生成樹kruskal算法.py
#思路 邊權重從小到大排序 從權重小的邊開始
#不形成回路就要,不然不要。直至包含所有點
#File Name : 并查集.py
# 并查集結構
from heapq import *
class Node(object):
pass
class UnionFindSet(object):
def __init__(self,nodes):
self.fatherDict = {}
# key node value father 一層一層向上找
self.sizeDict = {}
# key 節點 value 節點所在集合共有多少個節點
for node in nodes:
self.fatherDict[node]= node
self.sizeDict[node] = 1
#每個節點的父親是自己 并且所在的集合為個數為1
#因為要少挂多 ,是以要找節點數目
def FindHead(self,node):
stack = []
father = self.fatherDict[node]
while father!=node:
stack.append(node)
node = father
father = self.fatherDict[node]
while stack:
self.fatherDict[stack.pop()] = father
return father
def isSameSet(self,a,b):
return self.FindHead(a) == self.FindHead(b)
def uion(self,a,b):
if a is None or b is None:
return
aHead = self.FindHead(a)
bHead = self.FindHead(b)
if aHead!=bHead:
asize = self.sizeDict[aHead]
bsize = self.sizeDict[bHead]
if asize<=bsize:
self.fatherDict[aHead] = bHead
self.sizeDict[bHead] = asize+bsize
else:
self.fatherDict[bHead] = aHead
self.sizeDict[aHead] = asize+bsize
class Node(object):
def __init__(self,value=None):
self.value = value #節點的值
self.come = 0 #節點入度
self.out = 0 #節點出度
self.nexts = [] #節點的鄰居節點
self.edges = [] #在節點為from的情況下,邊的集合
class Edge(object):
def __init__(self,weight=None,fro,to):
self.weight = weight # 邊的權重
self.fro = fro # 邊的from節點
self.to = to #邊的to節點
def __lt__(self, other):
return self.weight<other.weight
class Graph(object):
def __init__(self):
self.nodes = {} #圖所有節點的集合 字典形式 :{節點編号:節點}
self.edges = [] #圖的邊集合
def creatGraph(matrix):
# 二維數組matrix [權重 從那個點的值 去哪個點的值]
graph = Graph()
# 建立所有節點
for edge in matrix:
weight = edge[0]
fro = edge[1]
to = edge[2]
if fro not in graph.nodes:
graph.nodes[fro] = Node(fro)
if to not in graph.nodes:
graph.nodes[to] = Node(to)
#建立所有的邊
fromNode = graph.nodes[fro]
toNode = graph.nodes[to]
newEdge = Edge(weight,fromNode,toNode)
fromNode.nexts.append(toNode) #加上鄰居指向
fromNode.out+=1 #出度+1
toNode.come+=1 #to 的入度+1
fromNode.edge.append(newEdge) #邊的集合+1
graph.edges.append(newEdge)
return graph
#k算法 堆結構 并查集結構 圖結構
def kruskalMST(graph):
unionfind = UnionFindSet(graph.nodes.values())
heapq = []
for edge in graph.edges:
heappush(heapq,edge)
res = set()
while len(heapq)>0:
edge = heappop(heapq)
if unionfind.isSameSet(edge.fro,edge.to)==False:
res.add(edge)
unionfind.uion(edge.fro,edge.to)
return res