【问题描述】Kruskal算法解决的是带权重的无向图上连接所有顶点的耗费最小的生成树。
【输入形式】在屏幕上输入顶点个数和连接顶点间的边的权矩阵。
【输出形式】顺序输出按照贪心选择加入到MST中的每条边的顶点编号(编号小的在前)及权值。
【样例1输入】
8
0 15 7 0 0 0 0 10
15 0 0 0 0 0 0 0
7 0 0 9 12 5 0 0
0 0 9 0 0 0 0 0
0 0 12 0 0 6 0 0
0 0 5 0 6 0 14 8
0 0 0 0 0 14 0 3
10 0 0 0 0 8 3 0
【样例1输出】
7 8 3
3 6 5
5 6 6
1 3 7
6 8 8
3 4 9
1 2 15
【样例说明】
输入:顶点个数为8。连接顶点间边的权矩阵大小为8行8列,位置[i,j]上元素值表示第i个顶点到第j个顶点的距离,0表示两个顶点间没有边连接。
输出:顺序输出按照贪心选择加入到MST中的每条边的顶点编号(编号小的在前)及权值。
【评分标准】根据输入得到准确的输出。
import numpy as np
import heapq
class edge(object):
def __init__(self, come=0, to=0, dis=0):
self.come = come
self.to = to
self.dis = dis
def __repr__(self):
pass
def __lt__(self, other):
return self.dis < other.dis
class Heap(object):
def __init__(self):
self._queue = []
def push(self, item):
heapq.heappush(self._queue, item)
def pop(self):
if self._queue:
return heapq.heappop(self._queue)
else:
return None
def heapify(self):
heapq.heapify(self._queue)
@property
def queue(self):
return self._queue
"""class Unionfind(object):
def __init__(self, nodes):
self.fatherDict = {} # key:node, value:father
self.sizeDict = {} # key:node,value:节点所在集合有多少个节点
for node in nodes:
self.fatherDict[node] = node
self.sizeDict[node] = 1
def find(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 issame(self, a, b):
return self.find(a) == self.find(b)
def union(self, a, b):
if a is None or b is None:
return
aHead = self.find(a)
bHead = self.find(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"""
def find(x):
if x == pre[x]:
return x
else:
pre[x] = find(pre[x])
return pre[x]
# def find(x):
# r = x
# while r != pre[r]:
# r = pre[r]
# i = x
# while i != r:
# j = pre[i]
# pre[i] = r
# i = j
# return r
def join(x, y):
pre[find(x)] = find(y)
# def join(x, y):
# rank = [0]*100
# root1 = find(x)
# root2 = find(y)
# if root1 == root2:
# return
# if rank[root1] < rank[root2]:
# pre[root1] = root2
# else:
# if rank[root1] == rank[root2]:
# rank[root1] += 1
# pre[root2] = root1
def kruskal(c):
Q = Heap()
for i in c:
Q.push(i)
while Q.queue:
u = Q.pop()
if find(u.come) != find(u.to):
print(u.come+1, u.to+1, u.dis)
join(u.come, u.to)
Q.heapify()
def main():
n = int(input())
a = []
c = []
global pre
pre = []
for i in range(n):
a.append(list(map(int, input().rstrip().split())))
b = np.array(a).reshape(n, n)
for i in range(n):
for j in range(i, n):
if b[i, j]:
node = edge(i, j, b[i, j])
c.append(node)
for i in range(0, n):
pre.append(i)
kruskal(c)
if __name__ == '__main__':
main()
"""
8
0 15 7 0 0 0 0 10
15 0 0 0 0 0 0 0
7 0 0 9 12 5 0 0
0 0 9 0 0 0 0 0
0 0 12 0 0 6 0 0
0 0 5 0 6 0 14 8
0 0 0 0 0 14 0 3
10 0 0 0 0 8 3 0
"""