传送门: 1697. 检查边长度限制的路径是否存在
题目:
给你一个 n 个点组成的无向图边集 edgeList ,其中 edgeList[i] = [ui, vi, disi] 表示点 ui 和点 vi 之间有一条长度为 disi 的边。请注意,两个点之间可能有 超过一条边 。
给你一个查询数组queries ,其中 queries[j] = [pj, qj, limitj] ,你的任务是对于每个查询 queries[j] ,判断是否存在从 pj 到 qj 的路径,且这条路径上的每一条边都 严格小于 limitj 。
请你返回一个 布尔数组 answer ,其中 answer.length == queries.length ,当 queries[j] 的查询结果为 true 时, answer 第 j 个值为 true ,否则为 false 。
数据范围:
- 2 < = n < = 1 0 5 2 <= n <= 10^5 2<=n<=105
- 1 < = e d g e L i s t . l e n g t h , q u e r i e s . l e n g t h < = 1 0 5 1 <= edgeList.length, queries.length <= 10^5 1<=edgeList.length,queries.length<=105
- e d g e L i s t [ i ] . l e n g t h = = 3 edgeList[i].length == 3 edgeList[i].length==3
- q u e r i e s [ j ] . l e n g t h = = 3 queries[j].length == 3 queries[j].length==3
- 0 < = u i , v i , p j , q j < = n − 1 0 <= u_i, v_i, p_j, q_j <= n - 1 0<=ui,vi,pj,qj<=n−1
- u i ! = v i u_i != v_i ui!=vi
- p j ! = q j p_j != q_j pj!=qj
- 1 < = d i s i , l i m i t j < = 1 0 9 1 <= dis_i, limit_j <= 10^9 1<=disi,limitj<=109
- 两个点之间可能有 多条 边。
解题思路:
考虑 离线思想 ,先将边按 边权 从小到大排序,然后将 q u e r i e s queries queries 中的 l i m i t limit limit 从小到大排序。然后考虑对于当前的查询,将小于 当前 l i m i t limit limit 的边挑出来,用并查集去判断点是否联通,就可以判断是否满足要求。
这种思想值得我学习。
AC代码:
class Solution {
public:
const static int MAXN = 1e5 + 10;
vector<bool>res;
int p[MAXN];
static int cmp(const vector<int>&a, const vector<int>&b){
return a[2] < b[2];
}
int Fa(int x){
return x == p[x] ? x : p[x] = Fa(p[x]);
}
void merge(int u,int v){
int fu = Fa(u),fv = Fa(v);
if(fu != fv){
p[fu] = fv;
}
}
vector<bool> distanceLimitedPathsExist(int n, vector<vector<int>>& edgeList, vector<vector<int>>& queries) {
int m = edgeList.size(),queriesLen = queries.size();
for(int i = 0;i < n;i ++){
p[i] = i;
}
for(int i = 0;i < queriesLen;i ++){
res.push_back(false);
queries[i].push_back(i);
}
sort(edgeList.begin(),edgeList.end(),cmp);
sort(queries.begin(),queries.end(),cmp);
int now = 0;
for(int i = 0;i < queriesLen;i ++){
int limit = queries[i][2];
while(now < m && edgeList[now][2] < limit){
int u = edgeList[now][0],v = edgeList[now][1];
merge(u,v);
now ++;
}
int u = queries[i][0],v = queries[i][1];
if(Fa(u) == Fa(v)){
res[queries[i][3]] = true;
}
}
return res;
}
};