From ab64c52d2832b843f0a16bccb001d366b19a80ce Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 21 Nov 2023 20:01:03 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problem: No.1724 No.1724.Checking Existence of Edge Length Limited Paths II --- .../README.md | 332 ++++++++++++++++++ .../README_EN.md | 330 +++++++++++++++++ .../Solution.cpp | 70 ++++ .../Solution.go | 80 +++++ .../Solution.java | 64 ++++ .../Solution.py | 35 ++ .../Solution.ts | 68 ++++ 7 files changed, 979 insertions(+) create mode 100644 solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.cpp create mode 100644 solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.go create mode 100644 solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.java create mode 100644 solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.py create mode 100644 solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md index e1d4cb8b7007b..f54fa19563ac8 100644 --- a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md @@ -58,6 +58,8 @@ distanceLimitedPathsExist.query(0, 5, 6); // 返回 false。从 0 到 5 之间 +**方法一:可持久化并查集** + ### **Python3** @@ -65,7 +67,41 @@ distanceLimitedPathsExist.query(0, 5, 6); // 返回 false。从 0 到 5 之间 ```python +class PersistentUnionFind: + def __init__(self, n): + self.rank = [0] * n + self.p = list(range(n)) + self.version = [inf] * n + + def find(self, x, t=inf): + if self.p[x] == x or self.version[x] >= t: + return x + return self.find(self.p[x], t) + + def union(self, a, b, t): + pa, pb = self.find(a), self.find(b) + if pa == pb: + return False + if self.rank[pa] > self.rank[pb]: + self.version[pb] = t + self.p[pb] = pa + else: + self.version[pa] = t + self.p[pa] = pb + if self.rank[pa] == self.rank[pb]: + self.rank[pb] += 1 + return True + +class DistanceLimitedPathsExist: + def __init__(self, n: int, edgeList: List[List[int]]): + self.puf = PersistentUnionFind(n) + edgeList.sort(key=lambda x: x[2]) + for u, v, dis in edgeList: + self.puf.union(u, v, dis) + + def query(self, p: int, q: int, limit: int) -> bool: + return self.puf.find(p, limit) == self.puf.find(q, limit) ``` ### **Java** @@ -73,7 +109,303 @@ distanceLimitedPathsExist.query(0, 5, 6); // 返回 false。从 0 到 5 之间 ```java +class PersistentUnionFind { + private final int inf = 1 << 30; + private int[] rank; + private int[] parent; + private int[] version; + + public PersistentUnionFind(int n) { + rank = new int[n]; + parent = new int[n]; + version = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + version[i] = inf; + } + } + + public int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + public boolean union(int a, int b, int t) { + int pa = find(a, inf); + int pb = find(b, inf); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +} + +public class DistanceLimitedPathsExist { + private PersistentUnionFind puf; + + public DistanceLimitedPathsExist(int n, int[][] edgeList) { + puf = new PersistentUnionFind(n); + Arrays.sort(edgeList, (a, b) -> a[2] - b[2]); + for (var e : edgeList) { + puf.union(e[0], e[1], e[2]); + } + } + + public boolean query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist obj = new DistanceLimitedPathsExist(n, edgeList); + * boolean param_1 = obj.query(p,q,limit); + */ +``` + +### **C++** + +```cpp +class PersistentUnionFind { +private: + vector rank; + vector parent; + vector version; + +public: + PersistentUnionFind(int n) + : rank(n, 0) + , parent(n) + , version(n, INT_MAX) { + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + bool unionSet(int a, int b, int t) { + int pa = find(a, INT_MAX); + int pb = find(b, INT_MAX); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +}; + +class DistanceLimitedPathsExist { +private: + PersistentUnionFind puf; + +public: + DistanceLimitedPathsExist(int n, vector>& edgeList) + : puf(n) { + sort(edgeList.begin(), edgeList.end(), + [](const vector& a, const vector& b) { + return a[2] < b[2]; + }); + + for (const auto& edge : edgeList) { + puf.unionSet(edge[0], edge[1], edge[2]); + } + } + + bool query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +}; + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist* obj = new DistanceLimitedPathsExist(n, edgeList); + * bool param_1 = obj->query(p,q,limit); + */ +``` + +### **Go** + +```go +type PersistentUnionFind struct { + rank []int + parent []int + version []int +} + +func NewPersistentUnionFind(n int) *PersistentUnionFind { + rank := make([]int, n) + parent := make([]int, n) + version := make([]int, n) + + for i := 0; i < n; i++ { + parent[i] = i + } + + return &PersistentUnionFind{ + rank: rank, + parent: parent, + version: version, + } +} + +func (uf *PersistentUnionFind) find(x int, t int) int { + if uf.parent[x] == x || uf.version[x] >= t { + return x + } + return uf.find(uf.parent[x], t) +} + +func (uf *PersistentUnionFind) union(a, b, t int) bool { + pa := uf.find(a, int(^uint(0)>>1)) + pb := uf.find(b, int(^uint(0)>>1)) + + if pa == pb { + return false + } + + if uf.rank[pa] > uf.rank[pb] { + uf.version[pb] = t + uf.parent[pb] = pa + } else { + uf.version[pa] = t + uf.parent[pa] = pb + if uf.rank[pa] == uf.rank[pb] { + uf.rank[pb]++ + } + } + + return true +} + +type DistanceLimitedPathsExist struct { + puf *PersistentUnionFind +} + +func Constructor(n int, edgeList [][]int) DistanceLimitedPathsExist { + sort.Slice(edgeList, func(i, j int) bool { + return edgeList[i][2] < edgeList[j][2] + }) + + puf := NewPersistentUnionFind(n) + + for _, edge := range edgeList { + puf.union(edge[0], edge[1], edge[2]) + } + + return DistanceLimitedPathsExist{ + puf: puf, + } +} + +func (dle *DistanceLimitedPathsExist) Query(p, q, limit int) bool { + return dle.puf.find(p, limit) == dle.puf.find(q, limit) +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * obj := Constructor(n, edgeList); + * param_1 := obj.Query(p,q,limit); + */ +``` + +### **TypeScript** + +```ts +class PersistentUnionFind { + private rank: number[]; + private parent: number[]; + private version: number[]; + + constructor(n: number) { + this.rank = Array(n).fill(0); + this.parent = Array.from({ length: n }, (_, i) => i); + this.version = Array(n).fill(Infinity); + } + + find(x: number, t: number): number { + if (this.parent[x] === x || this.version[x] >= t) { + return x; + } + return this.find(this.parent[x], t); + } + + union(a: number, b: number, t: number): boolean { + const pa = this.find(a, Infinity); + const pb = this.find(b, Infinity); + + if (pa === pb) { + return false; + } + + if (this.rank[pa] > this.rank[pb]) { + this.version[pb] = t; + this.parent[pb] = pa; + } else { + this.version[pa] = t; + this.parent[pa] = pb; + if (this.rank[pa] === this.rank[pb]) { + this.rank[pb]++; + } + } + + return true; + } +} + +class DistanceLimitedPathsExist { + private puf: PersistentUnionFind; + + constructor(n: number, edgeList: number[][]) { + this.puf = new PersistentUnionFind(n); + edgeList.sort((a, b) => a[2] - b[2]); + for (const [u, v, dis] of edgeList) { + this.puf.union(u, v, dis); + } + } + + query(p: number, q: number, limit: number): boolean { + return this.puf.find(p, limit) === this.puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ ``` ### **...** diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md index cc82c5b0f5c27..1b9e961124e3b 100644 --- a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md @@ -54,13 +54,343 @@ distanceLimitedPathsExist.query(0, 5, 6); // return false. There are no paths fr ### **Python3** ```python +class PersistentUnionFind: + def __init__(self, n): + self.rank = [0] * n + self.p = list(range(n)) + self.version = [inf] * n + def find(self, x, t=inf): + if self.p[x] == x or self.version[x] >= t: + return x + return self.find(self.p[x], t) + + def union(self, a, b, t): + pa, pb = self.find(a), self.find(b) + if pa == pb: + return False + if self.rank[pa] > self.rank[pb]: + self.version[pb] = t + self.p[pb] = pa + else: + self.version[pa] = t + self.p[pa] = pb + if self.rank[pa] == self.rank[pb]: + self.rank[pb] += 1 + return True + + +class DistanceLimitedPathsExist: + def __init__(self, n: int, edgeList: List[List[int]]): + self.puf = PersistentUnionFind(n) + edgeList.sort(key=lambda x: x[2]) + for u, v, dis in edgeList: + self.puf.union(u, v, dis) + + def query(self, p: int, q: int, limit: int) -> bool: + return self.puf.find(p, limit) == self.puf.find(q, limit) ``` ### **Java** ```java +class PersistentUnionFind { + private final int inf = 1 << 30; + private int[] rank; + private int[] parent; + private int[] version; + + public PersistentUnionFind(int n) { + rank = new int[n]; + parent = new int[n]; + version = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + version[i] = inf; + } + } + + public int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + public boolean union(int a, int b, int t) { + int pa = find(a, inf); + int pb = find(b, inf); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +} + +public class DistanceLimitedPathsExist { + private PersistentUnionFind puf; + + public DistanceLimitedPathsExist(int n, int[][] edgeList) { + puf = new PersistentUnionFind(n); + Arrays.sort(edgeList, (a, b) -> a[2] - b[2]); + for (var e : edgeList) { + puf.union(e[0], e[1], e[2]); + } + } + + public boolean query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist obj = new DistanceLimitedPathsExist(n, edgeList); + * boolean param_1 = obj.query(p,q,limit); + */ +``` + +### **C++** + +```cpp +class PersistentUnionFind { +private: + vector rank; + vector parent; + vector version; + +public: + PersistentUnionFind(int n) + : rank(n, 0) + , parent(n) + , version(n, INT_MAX) { + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + bool unionSet(int a, int b, int t) { + int pa = find(a, INT_MAX); + int pb = find(b, INT_MAX); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +}; + +class DistanceLimitedPathsExist { +private: + PersistentUnionFind puf; + +public: + DistanceLimitedPathsExist(int n, vector>& edgeList) + : puf(n) { + sort(edgeList.begin(), edgeList.end(), + [](const vector& a, const vector& b) { + return a[2] < b[2]; + }); + + for (const auto& edge : edgeList) { + puf.unionSet(edge[0], edge[1], edge[2]); + } + } + + bool query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +}; + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist* obj = new DistanceLimitedPathsExist(n, edgeList); + * bool param_1 = obj->query(p,q,limit); + */ +``` + +### **Go** + +```go +type PersistentUnionFind struct { + rank []int + parent []int + version []int +} + +func NewPersistentUnionFind(n int) *PersistentUnionFind { + rank := make([]int, n) + parent := make([]int, n) + version := make([]int, n) + + for i := 0; i < n; i++ { + parent[i] = i + } + + return &PersistentUnionFind{ + rank: rank, + parent: parent, + version: version, + } +} + +func (uf *PersistentUnionFind) find(x int, t int) int { + if uf.parent[x] == x || uf.version[x] >= t { + return x + } + return uf.find(uf.parent[x], t) +} + +func (uf *PersistentUnionFind) union(a, b, t int) bool { + pa := uf.find(a, int(^uint(0)>>1)) + pb := uf.find(b, int(^uint(0)>>1)) + + if pa == pb { + return false + } + + if uf.rank[pa] > uf.rank[pb] { + uf.version[pb] = t + uf.parent[pb] = pa + } else { + uf.version[pa] = t + uf.parent[pa] = pb + if uf.rank[pa] == uf.rank[pb] { + uf.rank[pb]++ + } + } + + return true +} + +type DistanceLimitedPathsExist struct { + puf *PersistentUnionFind +} + +func Constructor(n int, edgeList [][]int) DistanceLimitedPathsExist { + sort.Slice(edgeList, func(i, j int) bool { + return edgeList[i][2] < edgeList[j][2] + }) + + puf := NewPersistentUnionFind(n) + + for _, edge := range edgeList { + puf.union(edge[0], edge[1], edge[2]) + } + + return DistanceLimitedPathsExist{ + puf: puf, + } +} + +func (dle *DistanceLimitedPathsExist) Query(p, q, limit int) bool { + return dle.puf.find(p, limit) == dle.puf.find(q, limit) +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * obj := Constructor(n, edgeList); + * param_1 := obj.Query(p,q,limit); + */ +``` + +### **TypeScript** + +```ts +class PersistentUnionFind { + private rank: number[]; + private parent: number[]; + private version: number[]; + + constructor(n: number) { + this.rank = Array(n).fill(0); + this.parent = Array.from({ length: n }, (_, i) => i); + this.version = Array(n).fill(Infinity); + } + + find(x: number, t: number): number { + if (this.parent[x] === x || this.version[x] >= t) { + return x; + } + return this.find(this.parent[x], t); + } + + union(a: number, b: number, t: number): boolean { + const pa = this.find(a, Infinity); + const pb = this.find(b, Infinity); + + if (pa === pb) { + return false; + } + + if (this.rank[pa] > this.rank[pb]) { + this.version[pb] = t; + this.parent[pb] = pa; + } else { + this.version[pa] = t; + this.parent[pa] = pb; + if (this.rank[pa] === this.rank[pb]) { + this.rank[pb]++; + } + } + + return true; + } +} + +class DistanceLimitedPathsExist { + private puf: PersistentUnionFind; + + constructor(n: number, edgeList: number[][]) { + this.puf = new PersistentUnionFind(n); + edgeList.sort((a, b) => a[2] - b[2]); + for (const [u, v, dis] of edgeList) { + this.puf.union(u, v, dis); + } + } + + query(p: number, q: number, limit: number): boolean { + return this.puf.find(p, limit) === this.puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ ``` ### **...** diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.cpp b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.cpp new file mode 100644 index 0000000000000..5b9a49720d440 --- /dev/null +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.cpp @@ -0,0 +1,70 @@ +class PersistentUnionFind { +private: + vector rank; + vector parent; + vector version; + +public: + PersistentUnionFind(int n) + : rank(n, 0) + , parent(n) + , version(n, INT_MAX) { + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + bool unionSet(int a, int b, int t) { + int pa = find(a, INT_MAX); + int pb = find(b, INT_MAX); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +}; + +class DistanceLimitedPathsExist { +private: + PersistentUnionFind puf; + +public: + DistanceLimitedPathsExist(int n, vector>& edgeList) + : puf(n) { + sort(edgeList.begin(), edgeList.end(), + [](const vector& a, const vector& b) { + return a[2] < b[2]; + }); + + for (const auto& edge : edgeList) { + puf.unionSet(edge[0], edge[1], edge[2]); + } + } + + bool query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +}; + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist* obj = new DistanceLimitedPathsExist(n, edgeList); + * bool param_1 = obj->query(p,q,limit); + */ \ No newline at end of file diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.go b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.go new file mode 100644 index 0000000000000..2d716c5bf038c --- /dev/null +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.go @@ -0,0 +1,80 @@ +type PersistentUnionFind struct { + rank []int + parent []int + version []int +} + +func NewPersistentUnionFind(n int) *PersistentUnionFind { + rank := make([]int, n) + parent := make([]int, n) + version := make([]int, n) + + for i := 0; i < n; i++ { + parent[i] = i + } + + return &PersistentUnionFind{ + rank: rank, + parent: parent, + version: version, + } +} + +func (uf *PersistentUnionFind) find(x int, t int) int { + if uf.parent[x] == x || uf.version[x] >= t { + return x + } + return uf.find(uf.parent[x], t) +} + +func (uf *PersistentUnionFind) union(a, b, t int) bool { + pa := uf.find(a, int(^uint(0)>>1)) + pb := uf.find(b, int(^uint(0)>>1)) + + if pa == pb { + return false + } + + if uf.rank[pa] > uf.rank[pb] { + uf.version[pb] = t + uf.parent[pb] = pa + } else { + uf.version[pa] = t + uf.parent[pa] = pb + if uf.rank[pa] == uf.rank[pb] { + uf.rank[pb]++ + } + } + + return true +} + +type DistanceLimitedPathsExist struct { + puf *PersistentUnionFind +} + +func Constructor(n int, edgeList [][]int) DistanceLimitedPathsExist { + sort.Slice(edgeList, func(i, j int) bool { + return edgeList[i][2] < edgeList[j][2] + }) + + puf := NewPersistentUnionFind(n) + + for _, edge := range edgeList { + puf.union(edge[0], edge[1], edge[2]) + } + + return DistanceLimitedPathsExist{ + puf: puf, + } +} + +func (dle *DistanceLimitedPathsExist) Query(p, q, limit int) bool { + return dle.puf.find(p, limit) == dle.puf.find(q, limit) +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * obj := Constructor(n, edgeList); + * param_1 := obj.Query(p,q,limit); + */ \ No newline at end of file diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.java b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.java new file mode 100644 index 0000000000000..47b6276c9dbff --- /dev/null +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.java @@ -0,0 +1,64 @@ +class PersistentUnionFind { + private final int inf = 1 << 30; + private int[] rank; + private int[] parent; + private int[] version; + + public PersistentUnionFind(int n) { + rank = new int[n]; + parent = new int[n]; + version = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + version[i] = inf; + } + } + + public int find(int x, int t) { + if (parent[x] == x || version[x] >= t) { + return x; + } + return find(parent[x], t); + } + + public boolean union(int a, int b, int t) { + int pa = find(a, inf); + int pb = find(b, inf); + if (pa == pb) { + return false; + } + if (rank[pa] > rank[pb]) { + version[pb] = t; + parent[pb] = pa; + } else { + version[pa] = t; + parent[pa] = pb; + if (rank[pa] == rank[pb]) { + rank[pb]++; + } + } + return true; + } +} + +public class DistanceLimitedPathsExist { + private PersistentUnionFind puf; + + public DistanceLimitedPathsExist(int n, int[][] edgeList) { + puf = new PersistentUnionFind(n); + Arrays.sort(edgeList, (a, b) -> a[2] - b[2]); + for (var e : edgeList) { + puf.union(e[0], e[1], e[2]); + } + } + + public boolean query(int p, int q, int limit) { + return puf.find(p, limit) == puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * DistanceLimitedPathsExist obj = new DistanceLimitedPathsExist(n, edgeList); + * boolean param_1 = obj.query(p,q,limit); + */ \ No newline at end of file diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.py b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.py new file mode 100644 index 0000000000000..ec712afb724a0 --- /dev/null +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.py @@ -0,0 +1,35 @@ +class PersistentUnionFind: + def __init__(self, n): + self.rank = [0] * n + self.p = list(range(n)) + self.version = [inf] * n + + def find(self, x, t=inf): + if self.p[x] == x or self.version[x] >= t: + return x + return self.find(self.p[x], t) + + def union(self, a, b, t): + pa, pb = self.find(a), self.find(b) + if pa == pb: + return False + if self.rank[pa] > self.rank[pb]: + self.version[pb] = t + self.p[pb] = pa + else: + self.version[pa] = t + self.p[pa] = pb + if self.rank[pa] == self.rank[pb]: + self.rank[pb] += 1 + return True + + +class DistanceLimitedPathsExist: + def __init__(self, n: int, edgeList: List[List[int]]): + self.puf = PersistentUnionFind(n) + edgeList.sort(key=lambda x: x[2]) + for u, v, dis in edgeList: + self.puf.union(u, v, dis) + + def query(self, p: int, q: int, limit: int) -> bool: + return self.puf.find(p, limit) == self.puf.find(q, limit) diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts new file mode 100644 index 0000000000000..1e7c8d28d395e --- /dev/null +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts @@ -0,0 +1,68 @@ +class PersistentUnionFind { + private rank: number[]; + private parent: number[]; + private version: number[]; + + constructor(n: number) { + this.rank = Array(n).fill(0); + this.parent = Array.from({ length: n }, (_, i) => i); + this.version = Array(n).fill(Infinity); + } + + find(x: number, t: number): number { + if (this.parent[x] === x || this.version[x] >= t) { + return x; + } + return this.find(this.parent[x], t); + } + + union(a: number, b: number, t: number): boolean { + const pa = this.find(a, Infinity); + const pb = this.find(b, Infinity); + + if (pa === pb) { + return false; + } + + if (this.rank[pa] > this.rank[pb]) { + this.version[pb] = t; + this.parent[pb] = pa; + } else { + this.version[pa] = t; + this.parent[pa] = pb; + if (this.rank[pa] === this.rank[pb]) { + this.rank[pb]++; + } + } + + return true; + } +} + +class DistanceLimitedPathsExist { + private puf: PersistentUnionFind; + + constructor(n: number, edgeList: number[][]) { + this.puf = new PersistentUnionFind(n); + edgeList.sort((a, b) => a[2] - b[2]); + for (const [u, v, dis] of edgeList) { + this.puf.union(u, v, dis); + } + } + + query(p: number, q: number, limit: number): boolean { + return this.puf.find(p, limit) === this.puf.find(q, limit); + } +} + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ + +/** + * Your DistanceLimitedPathsExist object will be instantiated and called as such: + * var obj = new DistanceLimitedPathsExist(n, edgeList) + * var param_1 = obj.query(p,q,limit) + */ From 13b2cd951d4b9e750a5ee970b0870eb9202f7004 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 21 Nov 2023 20:04:40 +0800 Subject: [PATCH 2/2] fix: code --- .../README.md | 6 ------ .../README_EN.md | 6 ------ .../Solution.ts | 6 ------ 3 files changed, 18 deletions(-) diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md index f54fa19563ac8..db8c358982c8c 100644 --- a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README.md @@ -395,12 +395,6 @@ class DistanceLimitedPathsExist { } } -/** - * Your DistanceLimitedPathsExist object will be instantiated and called as such: - * var obj = new DistanceLimitedPathsExist(n, edgeList) - * var param_1 = obj.query(p,q,limit) - */ - /** * Your DistanceLimitedPathsExist object will be instantiated and called as such: * var obj = new DistanceLimitedPathsExist(n, edgeList) diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md index 1b9e961124e3b..0a28ab49f72b5 100644 --- a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/README_EN.md @@ -380,12 +380,6 @@ class DistanceLimitedPathsExist { } } -/** - * Your DistanceLimitedPathsExist object will be instantiated and called as such: - * var obj = new DistanceLimitedPathsExist(n, edgeList) - * var param_1 = obj.query(p,q,limit) - */ - /** * Your DistanceLimitedPathsExist object will be instantiated and called as such: * var obj = new DistanceLimitedPathsExist(n, edgeList) diff --git a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts index 1e7c8d28d395e..3707ae91c1957 100644 --- a/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts +++ b/solution/1700-1799/1724.Checking Existence of Edge Length Limited Paths II/Solution.ts @@ -60,9 +60,3 @@ class DistanceLimitedPathsExist { * var obj = new DistanceLimitedPathsExist(n, edgeList) * var param_1 = obj.query(p,q,limit) */ - -/** - * Your DistanceLimitedPathsExist object will be instantiated and called as such: - * var obj = new DistanceLimitedPathsExist(n, edgeList) - * var param_1 = obj.query(p,q,limit) - */