|
| 1 | +/** |
| 2 | + * @param {number} n |
| 3 | + * @param {number[][]} edgeList |
| 4 | + * @param {number[][]} queries |
| 5 | + * @return {boolean[]} |
| 6 | + */ |
| 7 | +const distanceLimitedPathsExist = function(n, edgeList, queries) { |
| 8 | + edgeList.sort((a, b) => a[2] - b[2]) |
| 9 | + let q = queries.length; |
| 10 | + const ans = Array(q).fill(false); |
| 11 | + const order = Array(q).fill(0); |
| 12 | + for (let i = 0; i < q; ++i) order[i] = i; |
| 13 | + order.sort((i, j) => queries[i][2] - queries[j][2]) |
| 14 | + const uf = new UnionFind(n); |
| 15 | + let idx = 0; |
| 16 | + for (let i of order) { |
| 17 | + let limit = queries[i][2]; |
| 18 | + while (idx < edgeList.length && edgeList[idx][2] < limit) { |
| 19 | + let u = edgeList[idx][0], v = edgeList[idx][1]; |
| 20 | + uf.union(u, v); |
| 21 | + idx++; |
| 22 | + } |
| 23 | + let u0 = queries[i][0], v0 = queries[i][1]; |
| 24 | + if (uf.find(u0) === uf.find(v0)) ans[i] = true; |
| 25 | + } |
| 26 | + return ans; |
| 27 | +}; |
| 28 | +class UnionFind { |
| 29 | + constructor(n) { |
| 30 | + this.parents = Array(n) |
| 31 | + .fill(0) |
| 32 | + .map((e, i) => i) |
| 33 | + this.ranks = Array(n).fill(0) |
| 34 | + } |
| 35 | + root(x) { |
| 36 | + while(x !== this.parents[x]) { |
| 37 | + this.parents[x] = this.parents[this.parents[x]] |
| 38 | + x = this.parents[x] |
| 39 | + } |
| 40 | + return x |
| 41 | + } |
| 42 | + find(x) { |
| 43 | + return this.root(x) |
| 44 | + } |
| 45 | + check(x, y) { |
| 46 | + return this.root(x) === this.root(y) |
| 47 | + } |
| 48 | + union(x, y) { |
| 49 | + const [rx, ry] = [this.find(x), this.find(y)] |
| 50 | + if (this.ranks[rx] >= this.ranks[ry]) { |
| 51 | + this.parents[ry] = rx |
| 52 | + this.ranks[rx] += this.ranks[ry] |
| 53 | + } else if (this.ranks[ry] > this.ranks[rx]) { |
| 54 | + this.parents[rx] = ry |
| 55 | + this.ranks[ry] += this.ranks[rx] |
| 56 | + } |
| 57 | + } |
| 58 | +} |
0 commit comments