最小生成树(prim贪心算法)

**【问题描述】**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
'''

发布了110 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40486952/article/details/90678262