Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ea860e7

Browse files
feat: add solutions to lc problem: No.3108 (doocs#2552)
No.3108.Minimum Cost Walk in Weighted Graph
1 parent b95ccf3 commit ea860e7

File tree

7 files changed

+951
-8
lines changed

7 files changed

+951
-8
lines changed

‎solution/3100-3199/3108.Minimum Cost Walk in Weighted Graph/README.md‎

Lines changed: 322 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,342 @@
7070

7171
## 解法
7272

73-
### 方法一
73+
### 方法一:贪心 + 并查集
74+
75+
我们注意到,一个正整数与其他若干个正整数不断进行"按位与"运算,结果只会越来越小。因此,为了使得旅途的代价尽可能小,我们应该将处于同一个连通分量的所有边的权值进行"按位与"运算,然后再进行查询。
76+
77+
那么,问题转化为,如何找出同一个连通份量的所有边,然后进行"按位与"运算。
78+
79+
我们可以用并查集来维护连通分量。
80+
81+
具体地,我们遍历每一条边 $(u, v, w),ドル将 $u$ 和 $v$ 进行合并。然后,我们再一次遍历每一条边 $(u, v, w),ドル找到 $u$ 和 $v$ 所在的连通分量的根节点 $root,ドル用一个数组 $g$ 记录每个连通分量的所有边的权值进行"按位与"运算的结果。
82+
83+
最后,对于每一个查询 $(s, t),ドル我们首先判断 $s$ 与 $t$ 是否相等,如果相等,那么答案为 0ドル,ドル否则,我们判断 $s$ 和 $t$ 是否在同一个连通分量中,如果在同一个连通分量中,那么答案为该查询的连通分量的根节点的 $g$ 值,否则,答案为 $-1$。
84+
85+
时间复杂度 $O((n + m + q) \times \alpha(n)),ドル空间复杂度 $O(n)$。其中 $n,ドル $m$ 和 $q$ 分别表示节点数、边数和查询数,而 $\alpha(n)$ 表示 Ackermann 函数的反函数。
7486

7587
<!-- tabs:start -->
7688

7789
```python
78-
90+
class UnionFind:
91+
def __init__(self, n):
92+
self.p = list(range(n))
93+
self.size = [1] * n
94+
95+
def find(self, x):
96+
if self.p[x] != x:
97+
self.p[x] = self.find(self.p[x])
98+
return self.p[x]
99+
100+
def union(self, a, b):
101+
pa, pb = self.find(a), self.find(b)
102+
if pa == pb:
103+
return False
104+
if self.size[pa] > self.size[pb]:
105+
self.p[pb] = pa
106+
self.size[pa] += self.size[pb]
107+
else:
108+
self.p[pa] = pb
109+
self.size[pb] += self.size[pa]
110+
return True
111+
112+
113+
class Solution:
114+
def minimumCost(
115+
self, n: int, edges: List[List[int]], query: List[List[int]]
116+
) -> List[int]:
117+
g = [-1] * n
118+
uf = UnionFind(n)
119+
for u, v, _ in edges:
120+
uf.union(u, v)
121+
for u, _, w in edges:
122+
root = uf.find(u)
123+
g[root] &= w
124+
125+
def f(u: int, v: int) -> int:
126+
if u == v:
127+
return 0
128+
a, b = uf.find(u), uf.find(v)
129+
return g[a] if a == b else -1
130+
131+
return [f(s, t) for s, t in query]
79132
```
80133

81134
```java
82-
135+
class UnionFind {
136+
private final int[] p;
137+
private final int[] size;
138+
139+
public UnionFind(int n) {
140+
p = new int[n];
141+
size = new int[n];
142+
for (int i = 0; i < n; ++i) {
143+
p[i] = i;
144+
size[i] = 1;
145+
}
146+
}
147+
148+
public int find(int x) {
149+
if (p[x] != x) {
150+
p[x] = find(p[x]);
151+
}
152+
return p[x];
153+
}
154+
155+
public boolean union(int a, int b) {
156+
int pa = find(a), pb = find(b);
157+
if (pa == pb) {
158+
return false;
159+
}
160+
if (size[pa] > size[pb]) {
161+
p[pb] = pa;
162+
size[pa] += size[pb];
163+
} else {
164+
p[pa] = pb;
165+
size[pb] += size[pa];
166+
}
167+
return true;
168+
}
169+
170+
public int size(int x) {
171+
return size[find(x)];
172+
}
173+
}
174+
175+
class Solution {
176+
private UnionFind uf;
177+
private int[] g;
178+
179+
public int[] minimumCost(int n, int[][] edges, int[][] query) {
180+
uf = new UnionFind(n);
181+
for (var e : edges) {
182+
uf.union(e[0], e[1]);
183+
}
184+
g = new int[n];
185+
Arrays.fill(g, -1);
186+
for (var e : edges) {
187+
int root = uf.find(e[0]);
188+
g[root] &= e[2];
189+
}
190+
int m = query.length;
191+
int[] ans = new int[m];
192+
for (int i = 0; i < m; ++i) {
193+
int s = query[i][0], t = query[i][1];
194+
ans[i] = f(s, t);
195+
}
196+
return ans;
197+
}
198+
199+
private int f(int u, int v) {
200+
if (u == v) {
201+
return 0;
202+
}
203+
int a = uf.find(u), b = uf.find(v);
204+
return a == b ? g[a] : -1;
205+
}
206+
}
83207
```
84208

85209
```cpp
86-
210+
class UnionFind {
211+
public:
212+
UnionFind(int n) {
213+
p = vector<int>(n);
214+
size = vector<int>(n, 1);
215+
iota(p.begin(), p.end(), 0);
216+
}
217+
218+
bool unite(int a, int b) {
219+
int pa = find(a), pb = find(b);
220+
if (pa == pb) {
221+
return false;
222+
}
223+
if (size[pa] > size[pb]) {
224+
p[pb] = pa;
225+
size[pa] += size[pb];
226+
} else {
227+
p[pa] = pb;
228+
size[pb] += size[pa];
229+
}
230+
return true;
231+
}
232+
233+
int find(int x) {
234+
if (p[x] != x) {
235+
p[x] = find(p[x]);
236+
}
237+
return p[x];
238+
}
239+
240+
int getSize(int x) {
241+
return size[find(x)];
242+
}
243+
244+
private:
245+
vector<int> p, size;
246+
};
247+
248+
class Solution {
249+
public:
250+
vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
251+
g = vector<int>(n, -1);
252+
uf = new UnionFind(n);
253+
for (auto& e : edges) {
254+
uf->unite(e[0], e[1]);
255+
}
256+
for (auto& e : edges) {
257+
int root = uf->find(e[0]);
258+
g[root] &= e[2];
259+
}
260+
vector<int> ans;
261+
for (auto& q : query) {
262+
ans.push_back(f(q[0], q[1]));
263+
}
264+
return ans;
265+
}
266+
267+
private:
268+
UnionFind* uf;
269+
vector<int> g;
270+
271+
int f(int u, int v) {
272+
if (u == v) {
273+
return 0;
274+
}
275+
int a = uf->find(u), b = uf->find(v);
276+
return a == b ? g[a] : -1;
277+
}
278+
};
87279
```
88280
89281
```go
282+
type unionFind struct {
283+
p, size []int
284+
}
285+
286+
func newUnionFind(n int) *unionFind {
287+
p := make([]int, n)
288+
size := make([]int, n)
289+
for i := range p {
290+
p[i] = i
291+
size[i] = 1
292+
}
293+
return &unionFind{p, size}
294+
}
295+
296+
func (uf *unionFind) find(x int) int {
297+
if uf.p[x] != x {
298+
uf.p[x] = uf.find(uf.p[x])
299+
}
300+
return uf.p[x]
301+
}
302+
303+
func (uf *unionFind) union(a, b int) bool {
304+
pa, pb := uf.find(a), uf.find(b)
305+
if pa == pb {
306+
return false
307+
}
308+
if uf.size[pa] > uf.size[pb] {
309+
uf.p[pb] = pa
310+
uf.size[pa] += uf.size[pb]
311+
} else {
312+
uf.p[pa] = pb
313+
uf.size[pb] += uf.size[pa]
314+
}
315+
return true
316+
}
317+
318+
func (uf *unionFind) getSize(x int) int {
319+
return uf.size[uf.find(x)]
320+
}
321+
322+
func minimumCost(n int, edges [][]int, query [][]int) (ans []int) {
323+
uf := newUnionFind(n)
324+
g := make([]int, n)
325+
for i := range g {
326+
g[i] = -1
327+
}
328+
for _, e := range edges {
329+
uf.union(e[0], e[1])
330+
}
331+
for _, e := range edges {
332+
root := uf.find(e[0])
333+
g[root] &= e[2]
334+
}
335+
f := func(u, v int) int {
336+
if u == v {
337+
return 0
338+
}
339+
a, b := uf.find(u), uf.find(v)
340+
if a == b {
341+
return g[a]
342+
}
343+
return -1
344+
}
345+
for _, q := range query {
346+
ans = append(ans, f(q[0], q[1]))
347+
}
348+
return
349+
}
350+
```
90351

352+
```ts
353+
class UnionFind {
354+
p: number[];
355+
size: number[];
356+
constructor(n: number) {
357+
this.p = Array(n)
358+
.fill(0)
359+
.map((_, i) => i);
360+
this.size = Array(n).fill(1);
361+
}
362+
363+
find(x: number): number {
364+
if (this.p[x] !== x) {
365+
this.p[x] = this.find(this.p[x]);
366+
}
367+
return this.p[x];
368+
}
369+
370+
union(a: number, b: number): boolean {
371+
const [pa, pb] = [this.find(a), this.find(b)];
372+
if (pa === pb) {
373+
return false;
374+
}
375+
if (this.size[pa] > this.size[pb]) {
376+
this.p[pb] = pa;
377+
this.size[pa] += this.size[pb];
378+
} else {
379+
this.p[pa] = pb;
380+
this.size[pb] += this.size[pa];
381+
}
382+
return true;
383+
}
384+
385+
getSize(x: number): number {
386+
return this.size[this.find(x)];
387+
}
388+
}
389+
390+
function minimumCost(n: number, edges: number[][], query: number[][]): number[] {
391+
const uf = new UnionFind(n);
392+
const g: number[] = Array(n).fill(-1);
393+
for (const [u, v, _] of edges) {
394+
uf.union(u, v);
395+
}
396+
for (const [u, _, w] of edges) {
397+
const root = uf.find(u);
398+
g[root] &= w;
399+
}
400+
const f = (u: number, v: number): number => {
401+
if (u === v) {
402+
return 0;
403+
}
404+
const [a, b] = [uf.find(u), uf.find(v)];
405+
return a === b ? g[a] : -1;
406+
};
407+
return query.map(([u, v]) => f(u, v));
408+
}
91409
```
92410

93411
<!-- tabs:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /