LC.P1697[检查边长度限制的路径是否存在]

方法一:离线查询+并查集

离线查询:对于一道题目会给出若干询问,而这些询问是全部提前给出的,也就是说,不必按照询问的顺序依次对它们进行处理,而是可以按照某种顺序(例如全序、偏序(拓扑序)、树的 DFS 序等)或者把所有询问看成一个整体(例如整体二分、莫队算法等)进行处理。

与「离线」相对应的是「在线」思维,即所有的询问是依次给出的,在返回第 $k$ 个询问的答案之前,不会获得第
$k+1$ 个询问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Solution {
int[] p;

private int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}

private void union(int a, int b) {
p[find(a)] = p[find(b)];
}

public boolean[] distanceLimitedPathsExist(int n, int[][] edgeList, int[][] queries) {
p = new int[n];
for (int i = 0; i < n; ++i) p[i] = i;
Arrays.sort(edgeList, (a, b) -> a[2] - b[2]);
int m = queries.length;
Integer[] index = new Integer[m];
for (int i = 0; i < m; ++i) index[i] = i;
Arrays.sort(index, (a, b) -> queries[a][2] - queries[b][2]);
boolean[] ans = new boolean[m];
int j = 0;
for (int i : index) {
int a = queries[i][0], b = queries[i][1], limit = queries[i][2];
while (j < edgeList.length && edgeList[j][2] < limit) {
int u = edgeList[j][0], v = edgeList[j][1];
union(u, v);
++j;
}
ans[i] = find(a) == find(b);
}
return ans;
}
}