LeetCode每日一题(1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree)

Given a weighted undirected connected graph with n vertices numbered from 0 to n - 1, and an array edges where edges[i] = [ai, bi, weighti] represents a bidirectional and weighted edge between nodes ai and bi. A minimum spanning tree (MST) is a subset of the graph’s edges that connects all vertices without cycles and with the minimum possible total edge weight.

Find all the critical and pseudo-critical edges in the given graph’s minimum spanning tree (MST). An MST edge whose deletion from the graph would cause the MST weight to increase is called a critical edge. On the other hand, a pseudo-critical edge is that which can appear in some MSTs but not all.

Note that you can return the indices of the edges in any order.

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 figure above describes the graph.
The following figure shows all the possible MSTs:

Notice that the two edges 0 and 1 appear in all MSTs, therefore they are critical edges, so we return them in the first list of the output.
The edges 2, 3, 4, and 5 are only part of some MSTs, therefore they are considered pseudo-critical edges. We add them to the second list of the 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: We can observe that since all 4 edges have equal weight, choosing any 3 edges from the given 4 will yield an MST. Therefore all 4 edges are pseudo-critical.

Constraints:

  • 2 <= n <= 100
  • 1 <= edges.length <= min(200, n * (n - 1) / 2)
  • edges[i].length == 3
  • 0 <= ai < bi < n
  • 1 <= weighti <= 1000
  • All pairs (ai, bi) are distinct.

用所有的 edges 建立 mst, 此时 mst 的 weight 我们记做 min_weight, 因为此时我们生成的 mst 的 weight 一定是最小的。

critical edge 的检查方法: 移除该 edge, 然后建立 mst, 如果 mst 的 weight > min_weight 则证明此 edge 是 critical edge

pseudo critical edge 的检查方法: 强制用该 edge 生成 mst, 如果生成的 mst 的 weight == min_weight 则此 edge 为 pseudo critical edge。其实换种方法理解就是该 edge 一定至少出现在一个 weight == min_weight 的 mst 中



impl Solution {
    fn find(parents: &mut Vec<usize>, n: usize) -> usize {
        if parents[n] == n {
            return n;
        }
        let p = Solution::find(parents, parents[n]);
        parents[n] = p;
        p
    }

    fn union(parents: &mut Vec<usize>, a: usize, b: usize) {
        let pa = Solution::find(parents, a);
        let pb = Solution::find(parents, b);
        parents[pa] = pb;
    }

    fn build_mst(n: i32, edges: &Vec<Vec<i32>>, pass: Option<usize>, must_included: Option<usize>) -> i32 {
        let mut num_of_components = n;
        let mut parents: Vec<usize> = (0..n as usize).into_iter().collect();
        let mut weight = 0;
        if let Some(i) = must_included {
            Solution::union(&mut parents, edges[i][0] as usize, edges[i][1] as usize);
            num_of_components -= 1;
            weight += edges[i][2];
        }
        for (i, edge) in edges.into_iter().enumerate() {
            if num_of_components == 1 {
                break;
            }
            if let Some(j) = pass {
                if i == j {
                    continue;
                }
            }
            if Solution::find(&mut parents, edge[0] as usize) == Solution::find(&mut parents, edge[1] as usize) {
                continue;
            }
            Solution::union(&mut parents, edge[0] as usize, edge[1] as usize);
            num_of_components -= 1;
            weight += edge[2];
        }
        if num_of_components > 1 {
            i32::MAX
        } else {
            weight
        }
    }

    pub fn find_critical_and_pseudo_critical_edges(n: i32, edges: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
        let mut edges: Vec<Vec<i32>> = edges
            .into_iter()
            .enumerate()
            .map(|(i, mut l)| {
                l.push(i as i32);
                l
            })
            .collect();
        edges.sort_by_key(|l| l[2]);
        let min_weight = Solution::build_mst(n, &edges, None, None);
        let mut critical_edges = Vec::new();
        let mut pseudo_critical_edges = Vec::new();
        for i in 0..edges.len() {
            if min_weight < Solution::build_mst(n, &edges, Some(i), None) {
                critical_edges.push(edges[i][3]);
                continue;
            }
            if min_weight == Solution::build_mst(n, &edges, None, Some(i)) {
                pseudo_critical_edges.push(edges[i][3]);
            }
        }
        vec![critical_edges, pseudo_critical_edges]
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值