---
# System prepended metadata

title: 1697. Checking Existence of Edge Length Limited Paths
tags: [Leetcode, Union Find, Hard]

---

# 1697. Checking Existence of Edge Length Limited Paths
###### tags: `Leetcode` `Hard` `Union Find`
Link: https://leetcode.com/problems/checking-existence-of-edge-length-limited-paths/description/
## 思路
我们考虑一下如果只有一个query的话我们会怎么做？显然，我们只要考虑所有权重小于limit的那些edges，看看这些edges能否把query的两个node连接在一起。这是一个典型的Union Find的解法，时间复杂度近似为O(E).

但是本题有多个queries，如果对于每个query都独立解决的话，时间复杂度大致是O(QE)，这样来看是会TLE的。

解决方案很简单。我们优先解决limit低的query，因为它所能用到的edge数目更少，我们只需要查看少量的edges看它是否能够成query两点的连通图。然后我们再解决limit较高的query，此时只需要在已经构建的图里面再添加若干个新edge即可（因为放宽了对权重的要求），再判断query的两点是否联通...可见，如果我们将所有的queries按照limit从小到大排列进行处理，那么相应地我们只需要按照权重从小到大地添加边就行了。在构建联通图的过程中，每条边只需要处理一遍。
## Code
```java=
class Solution {
    int[] fa;
    public boolean[] distanceLimitedPathsExist(int n, int[][] edgeList, int[][] queries) {      
        for(int i=0; i<queries.length; i++){
            int[] query = queries[i];
            queries[i] = new int[]{query[0], query[1], query[2], i};
        }
        Arrays.sort(edgeList, (a,b)->(a[2]-b[2]));
        Arrays.sort(queries, (a,b)->(a[2]-b[2]));
        boolean[] ans = new boolean[queries.length];
        int idx = 0;
        fa = new int[n];
        for(int i=0; i<n; i++) fa[i] = i;
        for(int i=0; i<queries.length; i++){
            int[] query = queries[i];
            while(idx<edgeList.length && edgeList[idx][2]<query[2]){
                int[] edge = edgeList[idx];
                combine(edge[0], edge[1]);
                idx++;
            }
            ans[query[3]] = find(query[0])==find(query[1]);
        }
        return ans;
    }
    private int find(int a){
        if(fa[a]==a) return a;
        return fa[a] = find(fa[a]);
    }
    private void combine(int a, int b){
        a = find(a);
        b = find(b);
        if(a!=b) fa[a] = b;
    }
}
```