📜  门| GATE-CS-2016(套装2)|第 58 题(1)

📅  最后修改于: 2023-12-03 15:12:43.521000             🧑  作者: Mango

GATE-CS-2016(套装2)|第 58 题

这道题目考察的是最小生成树算法,具体来说是 Kruskal 算法。在一张无向带权图中寻找最小生成树,Kruskal 算法将所有的边按权值从小到大排序,然后依次加入生成树中,但要保证新加入的边不会与已加入的边形成环。

算法实现
class Graph:
    def __init__(self, vertices):
        self.vertices = vertices
        self.graph = []
 
    def add_edge(self, src, dest, weight):
        self.graph.append([src, dest, weight])
 
    def find(self, parent, i):
        if parent[i] == i:
            return i
        return self.find(parent, parent[i])
 
    def union(self, parent, rank, x, y):
        xroot = self.find(parent, x)
        yroot = self.find(parent, y)
 
        if rank[xroot] < rank[yroot]:
            parent[xroot] = yroot
        elif rank[xroot] > rank[yroot]:
            parent[yroot] = xroot
        else:
            parent[yroot] = xroot
            rank[xroot] += 1
 
    def kruskal_mst(self):
        result = []
        i, e = 0, 0
        self.graph = sorted(self.graph, key=lambda item: item[2])
        parent = []
        rank = [0] * self.vertices
 
        for node in range(self.vertices):
            parent.append(node)
 
        while e < self.vertices - 1:
            src, dest, weight = self.graph[i]
            i = i + 1
            x = self.find(parent, src)
            y = self.find(parent, dest)
 
            if x != y:
                e = e + 1
                result.append([src, dest, weight])
                self.union(parent, rank, x, y)
 
        return result
测试样例

接下来,我们进行一些测试,看看程序是否能够正确计算无向带权图的最小生成树。

g = Graph(4)
g.add_edge(0, 1, 10)
g.add_edge(0, 2, 6)
g.add_edge(0, 3, 5)
g.add_edge(1, 3, 15)
g.add_edge(2, 3, 4)

print(g.kruskal_mst())

运行上述代码后,我们可以得到输出结果:

[[2, 3, 4], [0, 3, 5], [0, 1, 10]]

从输出结果可以看出,该程序确实能够计算出图的最小生成树,并按边的权值从小到大输出每条边。