Leetcode 周賽#220 D. 檢查邊長度限制的路徑是否存在 (並查集+離線)
阿新 • • 發佈:2021-01-04
Description
Solution
將詢問和邊集按照邊權從小到大排序後, 每次將比當前詢問的lim小的邊加入並查集中, 再判斷此時兩點是否連通即可
Code
class Solution {
public:
#define maxn 100005
int fa[maxn];
int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
struct node{
int u,v,lim;
int id;
inline bool operator <(const node&it) const{
return lim < it.lim;
}
};
vector<node>q, edge;
bool ans[maxn];
vector<bool>res;
inline void unionset(int u,int v) {
int f1 = find(u), f2 = find(v);
if(f1 == f2) return ;
fa[f1] = f2;
}
void init(int n) {
res.clear();
q.clear(), edge.clear();
for(int i = 0;i < n;++i) fa[i] = i;
}
vector<bool> distanceLimitedPathsExist(int n, vector<vector<int>>& edgeList, vector<vector<int>>& queries) {
init (n);
for(int i = 0;i < queries.size();++i) {
q.push_back((node){queries[i][0], queries[i][1], queries[i][2],i});
}
for(int i = 0;i < edgeList.size();++i) {
edge.push_back((node){edgeList[i][0], edgeList[i][1], edgeList[i][2],i});
}
sort(q.begin(), q.end());
sort(edge.begin(), edge.end());
int i = 0, sz1 = q.size(), sz2 = edge.size();
for(auto now : q) {
int lim = now.lim, id = now.id;
while(i < sz2 && edge[i].lim < lim) {
int u = edge[i].u, v = edge[i].v;
unionset(u,v);++i;
}
if(find(now.u) != find(now.v)) {
ans[id] = false;
} else ans[id] = true;
}
for(int i = 0;i < sz1;++i) {
res.push_back(ans[i]);
}return res;
}
};