LeetCode (1489. Find the key edge and pseudo key edge in the minimum spanning tree &&Python)

LeetCode (1489. Find the critical edge and pseudo-critical edge in the minimum spanning tree)


Give you a weighted undirected connected graph with n points, with nodes numbered from 0 to n-1, and an array of edges, where edges[i] = [fromi, toi, weighti] means that between fromi and toi nodes There is a weighted undirected edge in between. The minimum spanning tree (MST) is a subset of the edges in a given graph. It connects all nodes and has no loops, and the sum of the weights of these edges is the smallest.

Please find all key edges and pseudo key edges of the minimum spanning tree in a given graph. If an edge is deleted from the graph, it will lead to an increase in the weight of the minimum spanning tree, then we say that it is a critical edge. Pseudo critical edges are edges that may appear in some minimum spanning trees but not in all minimum spanning trees.

Please note that you can return the subscripts of key edges and pseudo-key edges in any order, respectively.

 

Example 1:

Input: n = 5, edges = [[0,1,1],[1,2,1],[2,3,2],[0,3,2],[0,4,3],[ 3,4,3],[1,4,6]]
Output: [[0,1],[2,3,4,5]]
Explanation: The above figure describes the given figure.
The figure below shows all the minimum spanning trees.

Note that the 0th edge and the 1st edge appear in all the minimum spanning trees, so they are the key edges. We use these two subscripts as the first list of output.
Edges 2, 3, 4 and 5 are the remaining edges of all MSTs, so they are pseudo-critical edges. We will use them as the second list of output.
Example 2:

Input: n = 4, edges = [[0,1,1],[1,2,1],[2,3,1],[0,3,1]]
Output: [[],[0, 1,2,3]]
Explanation: It can be observed that 4 edges have the same weight, and you can choose 3 of them to form an MST. So the 4 edges are all pseudo-critical edges.
 

prompt:

2 <= n <= 100
1 <= edges.length <= min(200, n * (n-1) / 2)
edges[i].length == 3
0 <= fromi <toi <n
1 <= weighti <= 1000
All (fromi, toi) pairs are different from each other.

Source: LeetCode
Link: Title Link

Problem solution: kruskal algorithm of Python solution

class Solution:
    def __init__(self):self.MAX_VALUE = 1e6
    def find(self, prev, node):       # 并查集模板
        if prev[node] != node:prev[node] = self.find(prev, prev[node])  # 路径压缩
        return prev[node]
    def kruskal(self, edges, n, k, remove=True):   # 克鲁斯卡尔算法找最小生成树
        prev = [i for i in range(n)]
        count, cost = 0, 0
        if not remove:                             # 必包含第k条边
            prev[self.backup[k][1]] = self.backup[k][0]
            cost = self.backup[k][2]
            count = 1
        for i, edge in enumerate(edges):
            if remove and k >= 0 and edge == self.backup[k]:continue  # 特殊情况不包含
            p1, p2 = self.find(prev, edge[0]), self.find(prev, edge[1])
            if p1 == p2: continue    # 同一棵树直接跳过
            prev[p2] = p1            # 两树合并
            cost += edge[2]
            count += 1
            if count == n - 1:return cost
        return self.MAX_VALUE
    def findCriticalAndPseudoCriticalEdges(self, n: int, edges: List[List[int]]) -> List[List[int]]:
        self.backup = [edge for edge in edges] # 保持顺序 不用深拷贝
        edges.sort(key=lambda x : x[2])        # 升序排序
        minCost = self.kruskal(edges, n, -1)
        result = [[], []]
        for i in range(len(edges)):
            if self.kruskal(edges, n, i) > minCost:result[0].append(i) # 关键边
            elif self.kruskal(edges, n, i, False) == minCost: result[1].append(i)  # 伪关键边
        return result

 

Guess you like

Origin blog.csdn.net/adminkeys/article/details/112917581