Skip to content

Commit ba842d7

Browse files
authored
feat: add solutions to lc problem: No.1724 (doocs#1996)
No.1724.Checking Existence of Edge Length Limited Paths II
1 parent d65afb2 commit ba842d7

File tree

7 files changed

+961
-0
lines changed

7 files changed

+961
-0
lines changed

solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md

+326
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,348 @@ distanceLimitedPathsExist.query(0, 5, 6); // 返回 false。从 0 到 5 之间
5858

5959
<!-- 这里可写通用的实现逻辑 -->
6060

61+
**方法一:可持久化并查集**
62+
6163
<!-- tabs:start -->
6264

6365
### **Python3**
6466

6567
<!-- 这里可写当前语言的特殊实现逻辑 -->
6668

6769
```python
70+
class PersistentUnionFind:
71+
def __init__(self, n):
72+
self.rank = [0] * n
73+
self.p = list(range(n))
74+
self.version = [inf] * n
75+
76+
def find(self, x, t=inf):
77+
if self.p[x] == x or self.version[x] >= t:
78+
return x
79+
return self.find(self.p[x], t)
80+
81+
def union(self, a, b, t):
82+
pa, pb = self.find(a), self.find(b)
83+
if pa == pb:
84+
return False
85+
if self.rank[pa] > self.rank[pb]:
86+
self.version[pb] = t
87+
self.p[pb] = pa
88+
else:
89+
self.version[pa] = t
90+
self.p[pa] = pb
91+
if self.rank[pa] == self.rank[pb]:
92+
self.rank[pb] += 1
93+
return True
94+
6895

96+
class DistanceLimitedPathsExist:
97+
def __init__(self, n: int, edgeList: List[List[int]]):
98+
self.puf = PersistentUnionFind(n)
99+
edgeList.sort(key=lambda x: x[2])
100+
for u, v, dis in edgeList:
101+
self.puf.union(u, v, dis)
102+
103+
def query(self, p: int, q: int, limit: int) -> bool:
104+
return self.puf.find(p, limit) == self.puf.find(q, limit)
69105
```
70106

71107
### **Java**
72108

73109
<!-- 这里可写当前语言的特殊实现逻辑 -->
74110

75111
```java
112+
class PersistentUnionFind {
113+
private final int inf = 1 << 30;
114+
private int[] rank;
115+
private int[] parent;
116+
private int[] version;
117+
118+
public PersistentUnionFind(int n) {
119+
rank = new int[n];
120+
parent = new int[n];
121+
version = new int[n];
122+
for (int i = 0; i < n; i++) {
123+
parent[i] = i;
124+
version[i] = inf;
125+
}
126+
}
127+
128+
public int find(int x, int t) {
129+
if (parent[x] == x || version[x] >= t) {
130+
return x;
131+
}
132+
return find(parent[x], t);
133+
}
134+
135+
public boolean union(int a, int b, int t) {
136+
int pa = find(a, inf);
137+
int pb = find(b, inf);
138+
if (pa == pb) {
139+
return false;
140+
}
141+
if (rank[pa] > rank[pb]) {
142+
version[pb] = t;
143+
parent[pb] = pa;
144+
} else {
145+
version[pa] = t;
146+
parent[pa] = pb;
147+
if (rank[pa] == rank[pb]) {
148+
rank[pb]++;
149+
}
150+
}
151+
return true;
152+
}
153+
}
154+
155+
public class DistanceLimitedPathsExist {
156+
private PersistentUnionFind puf;
157+
158+
public DistanceLimitedPathsExist(int n, int[][] edgeList) {
159+
puf = new PersistentUnionFind(n);
160+
Arrays.sort(edgeList, (a, b) -> a[2] - b[2]);
161+
for (var e : edgeList) {
162+
puf.union(e[0], e[1], e[2]);
163+
}
164+
}
165+
166+
public boolean query(int p, int q, int limit) {
167+
return puf.find(p, limit) == puf.find(q, limit);
168+
}
169+
}
170+
171+
/**
172+
* Your DistanceLimitedPathsExist object will be instantiated and called as such:
173+
* DistanceLimitedPathsExist obj = new DistanceLimitedPathsExist(n, edgeList);
174+
* boolean param_1 = obj.query(p,q,limit);
175+
*/
176+
```
177+
178+
### **C++**
179+
180+
```cpp
181+
class PersistentUnionFind {
182+
private:
183+
vector<int> rank;
184+
vector<int> parent;
185+
vector<int> version;
186+
187+
public:
188+
PersistentUnionFind(int n)
189+
: rank(n, 0)
190+
, parent(n)
191+
, version(n, INT_MAX) {
192+
for (int i = 0; i < n; i++) {
193+
parent[i] = i;
194+
}
195+
}
196+
197+
int find(int x, int t) {
198+
if (parent[x] == x || version[x] >= t) {
199+
return x;
200+
}
201+
return find(parent[x], t);
202+
}
203+
204+
bool unionSet(int a, int b, int t) {
205+
int pa = find(a, INT_MAX);
206+
int pb = find(b, INT_MAX);
207+
if (pa == pb) {
208+
return false;
209+
}
210+
if (rank[pa] > rank[pb]) {
211+
version[pb] = t;
212+
parent[pb] = pa;
213+
} else {
214+
version[pa] = t;
215+
parent[pa] = pb;
216+
if (rank[pa] == rank[pb]) {
217+
rank[pb]++;
218+
}
219+
}
220+
return true;
221+
}
222+
};
223+
224+
class DistanceLimitedPathsExist {
225+
private:
226+
PersistentUnionFind puf;
227+
228+
public:
229+
DistanceLimitedPathsExist(int n, vector<vector<int>>& edgeList)
230+
: puf(n) {
231+
sort(edgeList.begin(), edgeList.end(),
232+
[](const vector<int>& a, const vector<int>& b) {
233+
return a[2] < b[2];
234+
});
235+
236+
for (const auto& edge : edgeList) {
237+
puf.unionSet(edge[0], edge[1], edge[2]);
238+
}
239+
}
240+
241+
bool query(int p, int q, int limit) {
242+
return puf.find(p, limit) == puf.find(q, limit);
243+
}
244+
};
245+
246+
/**
247+
* Your DistanceLimitedPathsExist object will be instantiated and called as such:
248+
* DistanceLimitedPathsExist* obj = new DistanceLimitedPathsExist(n, edgeList);
249+
* bool param_1 = obj->query(p,q,limit);
250+
*/
251+
```
252+
253+
### **Go**
254+
255+
```go
256+
type PersistentUnionFind struct {
257+
rank []int
258+
parent []int
259+
version []int
260+
}
261+
262+
func NewPersistentUnionFind(n int) *PersistentUnionFind {
263+
rank := make([]int, n)
264+
parent := make([]int, n)
265+
version := make([]int, n)
266+
267+
for i := 0; i < n; i++ {
268+
parent[i] = i
269+
}
270+
271+
return &PersistentUnionFind{
272+
rank: rank,
273+
parent: parent,
274+
version: version,
275+
}
276+
}
277+
278+
func (uf *PersistentUnionFind) find(x int, t int) int {
279+
if uf.parent[x] == x || uf.version[x] >= t {
280+
return x
281+
}
282+
return uf.find(uf.parent[x], t)
283+
}
284+
285+
func (uf *PersistentUnionFind) union(a, b, t int) bool {
286+
pa := uf.find(a, int(^uint(0)>>1))
287+
pb := uf.find(b, int(^uint(0)>>1))
288+
289+
if pa == pb {
290+
return false
291+
}
292+
293+
if uf.rank[pa] > uf.rank[pb] {
294+
uf.version[pb] = t
295+
uf.parent[pb] = pa
296+
} else {
297+
uf.version[pa] = t
298+
uf.parent[pa] = pb
299+
if uf.rank[pa] == uf.rank[pb] {
300+
uf.rank[pb]++
301+
}
302+
}
303+
304+
return true
305+
}
306+
307+
type DistanceLimitedPathsExist struct {
308+
puf *PersistentUnionFind
309+
}
310+
311+
func Constructor(n int, edgeList [][]int) DistanceLimitedPathsExist {
312+
sort.Slice(edgeList, func(i, j int) bool {
313+
return edgeList[i][2] < edgeList[j][2]
314+
})
315+
316+
puf := NewPersistentUnionFind(n)
317+
318+
for _, edge := range edgeList {
319+
puf.union(edge[0], edge[1], edge[2])
320+
}
321+
322+
return DistanceLimitedPathsExist{
323+
puf: puf,
324+
}
325+
}
326+
327+
func (dle *DistanceLimitedPathsExist) Query(p, q, limit int) bool {
328+
return dle.puf.find(p, limit) == dle.puf.find(q, limit)
329+
}
330+
331+
/**
332+
* Your DistanceLimitedPathsExist object will be instantiated and called as such:
333+
* obj := Constructor(n, edgeList);
334+
* param_1 := obj.Query(p,q,limit);
335+
*/
336+
```
337+
338+
### **TypeScript**
339+
340+
```ts
341+
class PersistentUnionFind {
342+
private rank: number[];
343+
private parent: number[];
344+
private version: number[];
345+
346+
constructor(n: number) {
347+
this.rank = Array(n).fill(0);
348+
this.parent = Array.from({ length: n }, (_, i) => i);
349+
this.version = Array(n).fill(Infinity);
350+
}
351+
352+
find(x: number, t: number): number {
353+
if (this.parent[x] === x || this.version[x] >= t) {
354+
return x;
355+
}
356+
return this.find(this.parent[x], t);
357+
}
358+
359+
union(a: number, b: number, t: number): boolean {
360+
const pa = this.find(a, Infinity);
361+
const pb = this.find(b, Infinity);
362+
363+
if (pa === pb) {
364+
return false;
365+
}
366+
367+
if (this.rank[pa] > this.rank[pb]) {
368+
this.version[pb] = t;
369+
this.parent[pb] = pa;
370+
} else {
371+
this.version[pa] = t;
372+
this.parent[pa] = pb;
373+
if (this.rank[pa] === this.rank[pb]) {
374+
this.rank[pb]++;
375+
}
376+
}
377+
378+
return true;
379+
}
380+
}
381+
382+
class DistanceLimitedPathsExist {
383+
private puf: PersistentUnionFind;
384+
385+
constructor(n: number, edgeList: number[][]) {
386+
this.puf = new PersistentUnionFind(n);
387+
edgeList.sort((a, b) => a[2] - b[2]);
388+
for (const [u, v, dis] of edgeList) {
389+
this.puf.union(u, v, dis);
390+
}
391+
}
392+
393+
query(p: number, q: number, limit: number): boolean {
394+
return this.puf.find(p, limit) === this.puf.find(q, limit);
395+
}
396+
}
76397

398+
/**
399+
* Your DistanceLimitedPathsExist object will be instantiated and called as such:
400+
* var obj = new DistanceLimitedPathsExist(n, edgeList)
401+
* var param_1 = obj.query(p,q,limit)
402+
*/
77403
```
78404

79405
### **...**

0 commit comments

Comments
 (0)