LeetCode题解(1489):找到最小生成树里的关键边和伪关键边(Python)

该博客讨论了一种利用并查集和深度优先搜索算法来查找图中临界边和伪临界边的方法。在给定的边集合上,通过构建最小生成树并逐个移除边来检查哪些边是关键的,影响图的连通性,哪些是伪关键的,改变最小生成树的权重。整个过程涉及对图的遍历和并查集数据结构的操作,以确定边的重要性。
摘要由CSDN通过智能技术生成

题目:原题链接(困难)

标签:并查集、深度优先搜索、图

解法时间复杂度空间复杂度执行用时
Ans 1 (Python) O ( E 2 ) O(E^2) O(E2) O ( N + E ) O(N+E) O(N+E)1984ms (25.00%)
Ans 2 (Python)
Ans 3 (Python)

解法一:

class DSU1:
    def __init__(self, n: int):
        self._n = n
        self._array = [i for i in range(n)]
        self._size = [1] * n

        self.group_num = n  # 连通分支数量

    def find(self, i: int) -> int:
        if self._array[i] != i:
            self._array[i] = self.find(self._array[i])
        return self._array[i]

    def union(self, i: int, j: int) -> bool:
        i, j = self.find(i), self.find(j)
        if i != j:
            if self._size[i] >= self._size[j]:
                self._array[j] = i
                self._size[i] += self._size[j]
            else:
                self._array[i] = j
                self._size[j] += self._size[i]
            self.group_num -= 1
            return True
        else:
            return False

    def is_connected(self, i: int, j: int) -> bool:
        return self.find(i) == self.find(j)

    def __repr__(self):
        return str(len(self._array)) + ":" + str(self._array)


class Solution:
    def findCriticalAndPseudoCriticalEdges(self, n: int, edges: List[List[int]]) -> List[List[int]]:
        size = len(edges)

        for i, edge in enumerate(edges):
            edge.append(i)
        edges.sort(key=lambda x: x[2])

        # 计算当前情况下的最小生成树的权值最小和
        # O(E)
        dsu = DSU1(n)
        min_power = 0
        for i in range(size):
            if dsu.union(edges[i][0], edges[i][1]):
                min_power += edges[i][2]

        ans = [[], []]
        # 遍历每条边检查是否为关键边或伪关键边
        for i in range(size):
            # 判断是否是关键边
            dsu = DSU1(n)
            power = 0
            for j in range(size):
                if i != j and dsu.union(edges[j][0], edges[j][1]):
                    power += edges[j][2]
            if dsu.group_num != 1 or (dsu.group_num == 1 and power > min_power):
                ans[0].append(edges[i][3])
                continue

            # 判断是否是伪关键边
            dsu = DSU1(n)
            dsu.union(edges[i][0], edges[i][1])
            power = edges[i][2]
            for j in range(size):
                if i != j and dsu.union(edges[j][0], edges[j][1]):
                    power += edges[j][2]
            if power == min_power:
                ans[1].append(edges[i][3])

        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值