【问题描述】Prim算法解决的是带权重的无向图上连接所有顶点的耗费最小的生成树。
【输入形式】在屏幕上输入顶点个数和连接顶点间的边的权矩阵。
【输出形式】顺序输出按照贪心选择得到的各顶点序号,及该顶点的前驱顶点序号,及路径长度。
【样例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输出】
3 1 7
6 3 5
5 6 6
8 6 8
7 8 3
4 3 9
2 1 15
【样例说明】
输入: 顶点个数为8。
连接顶点间边的权矩阵大小为8行8列;
位置[i,j]上元素值表示第i个顶点到第j个顶点的距离;
0表示两个顶点间没有边连接。
输出: 顺序输出按照贪心选择得到的各顶点序号,及该顶点的前驱顶点序号,及路径长度。
【评分标准】根据输入得到准确的输出。
最小生成树
设G=(V, E)是无向连通带权图,即一个网络。E中每条边(v, w)的权为c[v][w]。如果G的一个子图G1是一棵包含G的所有顶点的树,则称G1为G的生成树。生成树上各边权的总和称为该生成树的耗费。
在G的所有生成树中,耗费最小的生成树称为G的最小生成树。
网络的最小生成树在实际中有广泛应用。例如,在设计通信网络时,用图的顶点表示城市,用边(v, w)的权c[v][w]表示建立城市v和城市w之间的通信v线路所需的费用,则最小生树就给出了建立通信网络的最经济的方案。
问题分析
Prim算法
代码
import numpy as np
def Prim(n, weights):
# lowcost[j]的值为weights[j][closet[j]]
lowcost = np.array(weights[0])
# closest[j]是j在S中的邻接顶点
closest = np.zeros(n)
# 确定节点是否使用
s = np.zeros(n, bool)
# 从节点1开始求最小生成树
s[0] = True
# 求邻接节点,循环n-1次;
for i in range(1, n):
# 设置一个变量用来存放最小值;
minNumber = float('inf')
j = 1
# 找到当前节点到其他节点的权值最小的点;
for k in range(1, n):
if lowcost[k] < minNumber and not s[k] and lowcost[k] != 0:
minNumber = lowcost[k]
j = k
print(j + 1, end=" ")
print(int(closest[j] + 1), end=" ")
print(weights[j][int(closest[j])])
# 将j放入S集合中
s[j] = True
# 更新lowcost中其他节点到S中节点最短距离
for k in range(1, n):
if not s[k] and weights[j][k] != 0:
if weights[j][k] < lowcost[k] or lowcost[k] == 0:
lowcost[k] = weights[j][k]
closest[k] = j
def main():
n = int(input())
weight = []
for i in range(n):
weight.append(list(map(int, input().rstrip().split())))
weights = np.array(weight).reshape(n, n)
Prim(n, weights)
if __name__ == '__main__':
main()
转载:https://blog.csdn.net/weixin_44171004/article/details/106315284
查看评论