**【问题描述】**Prim算法解决的是带权重的无向图上连接所有顶点的耗费最小的生成树。
**【输入形式】**在屏幕上输入顶点个数和连接顶点间的边的权矩阵。
**【输出形式】**从源到各个顶点的最短距离及路径。
【样例输入】
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
【样例输出】
15: 1<-2
7: 1<-3
9: 1<-3<-4
6: 1<-3<-6<-5
5: 1<-3<-6
3: 1<-3<-6<-8<-7
8: 1<-3<-6<-8
【样例说明】
输入:顶点个数为8。连接顶点间边的权矩阵大小为8行8列,位置[i,j]上元素值表示第i个顶点到第j个顶点的距离,0表示两个顶点间没有边连接。
输出:每行表示其余各顶点的值及其到起始点1的路径。
MAX = 999 # inf
class Start(object):
def __init__(self, arc, n):
self.arc = arc # 邻接矩阵
self.n = n # 节点个数
self.side = self.get_side()
def get_side(self): # 获取边数
count = 0
for i in range(self.n):
for j in range(i):
if self.arc[i][j] != 0: # 如果不是本身(!=0)或者不连接(!=-1)则为一条边
count += 1
return count
def prim(self):
s = [0] # 记录已经存在最小生成树的节点
q = [a for a in range(1, self.n)] # 还未连通的点
key = [MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX] # 各顶点值
path = ["1", "", "", "", "", "", "", ""] # 存放路径
while len(q) > 0: # 还有顶点没进入s的
v1, v2, temp = 0, 0, MAX # 定义标志变量 0代表自身,MAX代表不连通
for i in s: # extract_min
for j in q:
if self.arc[j][i] != 0:
if temp > self.arc[i][j]:
temp = self.arc[i][j]
v1 = i
v2 = j
key[v2] = self.arc[v1][v2]
path[v2] = str(path[v1])+"<-"+str(v2+1)
# print("temp=", temp, "v1=", v1, "v2=", v2)
for k in range(0, self.n):
if k not in s and self.arc[v2][k] != 0:
if arc[v2][k] < key[k]:
key[k] = arc[v2][k] # 修改顶点值
# path[k] = v2
s.append(v2) # 插入到最小生成树的节点
q.remove(v2) # 删除此节点
return key, path
if __name__ == "__main__":
n = int(input())
arc = [] # 邻接矩阵
for i in range(n):
arc.append(list(map(int, input().split())))
start = Start(arc, n) # 创建类的对象
key, path = start.prim()
for i in range(1, n):
print(key[i], end=": ")
print(path[i])
'''
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
15: 1<-2
7: 1<-3
9: 1<-3<-4
6: 1<-3<-6<-5
5: 1<-3<-6
3: 1<-3<-6<-8<-7
8: 1<-3<-6<-8
'''