找到最小生成树里的关键边和伪关键边
难度:
标签:
题目描述
给你一个 n
个点的带权无向连通图,节点编号为 0
到 n-1
,同时还有一个数组 edges
,其中 edges[i] = [from
i, toi, weighti]
表示在 fromi
和 toi
节点之间有一条带权无向边。最小生成树 (MST) 是给定图中边的一个子集,它连接了所有节点且没有环,而且这些边的权值和最小。
请你找到给定图中最小生成树的所有关键边和伪关键边。如果从图中删去某条边,会导致最小生成树的权值和增加,那么我们就说它是一条关键边。伪关键边则是可能会出现在某些最小生成树中但不会出现在所有最小生成树中的边。
请注意,你可以分别以任意顺序返回关键边的下标和伪关键边的下标。
示例 1:
输入:n = 5, edges = [[0,1,1],[1,2,1],[2,3,2],[0,3,2],[0,4,3],[3,4,3],[1,4,6]] 输出:[[0,1],[2,3,4,5]] 解释:上图描述了给定图。 下图是所有的最小生成树。注意到第 0 条边和第 1 条边出现在了所有最小生成树中,所以它们是关键边,我们将这两个下标作为输出的第一个列表。 边 2,3,4 和 5 是所有 MST 的剩余边,所以它们是伪关键边。我们将它们作为输出的第二个列表。
示例 2 :
输入:n = 4, edges = [[0,1,1],[1,2,1],[2,3,1],[0,3,1]] 输出:[[],[0,1,2,3]] 解释:可以观察到 4 条边都有相同的权值,任选它们中的 3 条可以形成一棵 MST 。所以 4 条边都是伪关键边。
提示:
2 <= n <= 100
1 <= edges.length <= min(200, n * (n - 1) / 2)
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti <= 1000
- 所有
(fromi, toi)
数对都是互不相同的。
代码结果
运行时间: 41 ms, 内存: 16.3 MB
解释
方法:
题解使用了并查集和Tarjan算法的结合来解决问题。首先,使用并查集帮助处理并识别最小生成树中的边。通过对边按权重排序,可以便捷地处理同权重的边,使用Tarjan算法来检测关键边(即桥)。算法的核心在于识别出所有权重相同的边组,并在这些组内使用Tarjan算法来查找桥,即关键边。这些关键边是在最小生成树中无法替代的,因此它们是必须的。对于不是桥的边,则标记为伪关键边,表示它们可能在某些最小生成树中出现。
时间复杂度:
O(m log m + m α(n) + n + m)
空间复杂度:
O(n + m)
代码细节讲解
🦆
在题解中,你是如何确定一条边具体是关键边还是伪关键边的?
▷🦆
为什么在处理边的权重相同的情况下,选择使用Tarjan算法来识别桥?这是否与边的权重有直接关系?
▷🦆
题解中提到'将自环边标记为-1',请问何为自环边,在这个上下文中它指的是什么?
▷🦆
在使用并查集识别最小生成树中的边时,如果并查集中两个节点已经在同一个集合中,为什么还需要检查它们之间的边?
▷