Leetcode 3108. Minimum Cost Walk in Weighted Graph

  • [Leetcode 3108. Minimum Cost Walk in Weighted Graph](#Leetcode 3108. Minimum Cost Walk in Weighted Graph)
    • [1. 解题思路](#1. 解题思路)
    • [2. 代码实现](#2. 代码实现)

1. 解题思路

这一题一开始被吓到了,因为想的是要求出query当中任意两个点的一个联通通路,使得cost最小,这个会是一个最优路径选择问题,然后query和点的数目又都是 1 0 5 10^5 105量级,就很唬人。

后来去看答案的时候才突然反应过来,这根本就是一个脑筋急转弯的题目。

题目要求的是求query当中任意两点的最小cost,而cost的定义是两点间通路上所有边的权重的位与操作 结果。也就是说,求的是位与操作的最小值,且节点可以反复经过,那么必然是经过的边越多,值越小,换句话说:

  • 任意两个点,如果他们联通,那么他们的最小cost就必然是和他们相连通的所有点上包含的边的位与操作结果;如果他们不连通,那么他们的结果就是 − 1 -1 −1。

因此,这道题本质上只需要快速判断任意两个点是否联通即可,因此就是一个典型的DSU(并查集)的问题,如果不了解DSU的读者,可以参阅一下我之前的拙作《经典算法:并查集(DSU)结构简介》,不过相关内容网上也都多的是,随便翻翻也就有了,这里也就不过多展开了,就是需要加一些额外地操作记录一下每一个集合的所有边的位与结果即可。

2. 代码实现

给出python代码实现如下:

python 复制代码
class DSU:
    def __init__(self, n):
        self.root = [i for i in range(n)]
        self.value = [-1 for _ in range(n)]
        
    def find(self, k):
        if self.root[k] != k:
            self.root[k] = self.find(self.root[k])
        return self.root[k]
    
    def union(self, u, v, w):
        x = self.find(u)
        y = self.find(v)
        if x != y:
            self.root[y] = x
        if self.value[x] == -1 and self.value[y] == -1:
            self.value[x] = w
        elif self.value[x] != -1 and self.value[y] == -1:
            self.value[x] = w & self.value[x]
        elif self.value[x] == -1 and self.value[y] != -1:
            self.value[x] = w & self.value[y]
        else:
            self.value[x] = self.value[y] & self.value[x] & w
        return



class Solution:
    def minimumCost(self, n: int, edges: List[List[int]], query: List[List[int]]) -> List[int]:
        dsu = DSU(n)
        for u, v, w in edges:
            dsu.union(u, v, w)
        
        def _query(u, v):
            x, y = dsu.find(u), dsu.find(v)
            if x != y:
                return -1
            return dsu.value[x]

        return [_query(u, v) for u, v in query]

提交代码评测得到:耗时1184ms,占用内存67.9MB。

相关推荐
让我们一起加油好吗9 天前
【数据结构】带权并查集
数据结构·c++·算法·并查集·带权并查集
Espresso Macchiato11 天前
Leetcode 3748. Count Stable Subarrays
算法·leetcode·职场和发展·leetcode hard·leetcode 3748·leetcode周赛476·区间求和
月半流苏14 天前
Problem: lab-week10-exercise02 Building a Fiber Network
c++·算法·并查集
让我们一起加油好吗14 天前
【数据结构】并查集(操作详解 + 模板 + 练习)
数据结构·算法·并查集·洛谷
Espresso Macchiato15 天前
Leetcode 3739. Count Subarrays With Majority Element II
leetcode hard·前序和数组·leetcode双周赛169·leetcode 3739
Espresso Macchiato1 个月前
Leetcode 3729. Count Distinct Subarrays Divisible by K in Sorted Array
leetcode·leetcode hard·容斥原理·leetcode 3729·leetcode周赛473·前序和数组
Espresso Macchiato1 个月前
Leetcode 3715. Sum of Perfect Square Ancestors
算法·leetcode·职场和发展·leetcode hard·树的遍历·leetcode 3715·leetcode周赛471
Espresso Macchiato2 个月前
Leetcode 3710. Maximum Partition Factor
leetcode·职场和发展·广度优先遍历·二分法·leetcode hard·leetcode 3710·leetcode双周赛167
Espresso Macchiato2 个月前
Leetcode 3700. Number of ZigZag Arrays II
动态规划·leetcode hard·矩阵乘法·leetcode 3700·leetcode周赛469
Espresso Macchiato2 个月前
Leetcode 3695. Maximize Alternating Sum Using Swaps
并查集·leetcode hard·dsu·uf·leetcode 3695·leetcode双周赛166