- [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。