LeetCode 5632. 檢查邊長度限制的路徑是否存在(排序+並查集)
技術標籤:LeetCode
文章目錄
1. 題目
給你一個 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
示例 1:
輸入:n = 3, edgeList = [[0,1,2],[1,2,4],[2,0,8],[1,0,16]],
queries = [[0,1,2],[0,2,5]]
輸出:[false,true]
解釋:上圖為給定的輸入資料。注意到 0 和 1 之間有兩條重邊,分別為 2 和 16 。
對於第一個查詢,0 和 1 之間沒有小於 2 的邊,所以我們返回 false 。
對於第二個查詢,有一條路徑(0 -> 1 -> 2)兩條邊都小於 5 ,所以這個查詢我們返回 true 。
示例 2:
輸入:n = 5,
edgeList = [[0,1,10],[1,2,5],[2,3,9],[3,4,13]],
queries = [[0,4,14],[1,4,13]]
輸出:[true,false]
解釋:上圖為給定資料。
提示:
2 <= n <= 10^5
1 <= edgeList.length, queries.length <= 10^5
edgeList[i].length == 3
queries[j].length == 3
0 <= ui, vi, pj, qj <= n - 1
ui != vi
pj != qj
1 <= disi, limitj <= 10^9
兩個點之間可能有 多條 邊。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/checking-existence-of-edge-length-limited-paths
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
2. 解題
並查集參考:資料結構–並查集(Disjoint-Set)
相關題目:
LeetCode 261. 以圖判樹(全部連通+邊數=V-1)
LeetCode 305. 島嶼數量 II(並查集)
LeetCode 323. 無向圖中連通分量的數目(並查集)
LeetCode 684. 冗餘連線(並查集)
LeetCode 685. 冗餘連線 II(並查集)
LeetCode 721. 賬戶合併(並查集)(字串合併)
LeetCode 737. 句子相似性 II(並查集)
LeetCode 886. 可能的二分法(著色DFS/BFS/拓展並查集)
LeetCode 947. 移除最多的同行或同列石頭(並查集)
LeetCode 990. 等式方程的可滿足性(並查集)
LeetCode 959. 由斜槓劃分區域(並查集)
LeetCode 1061. 按字典序排列最小的等效字串(並查集)
LeetCode 1101. 彼此熟識的最早時間(排序+並查集)
LeetCode 1202. 交換字串中的元素(並查集)
LeetCode 1319. 連通網路的操作次數(BFS/DFS/並查集)
LeetCode 5510. 保證圖可完全遍歷(並查集)
程式設計師面試金典 - 面試題 17.07. 嬰兒名字(並查集)
- limits 短的優先查詢,邊也排序,滿足要求的在並查集中合併兩點
class dsu{ //並查集
public:
vector<int> f;
dsu(int n)
{
f.resize(n);
for(int i = 0; i < n; ++i)
f[i] = i;
}
void merge(int a, int b)
{
int fa = find(a), fb = find(b);
f[fa] = fb;
}
int find(int a)
{
if(a == f[a])
return a;
return f[a] = find(f[a]);
}
};
class Solution {
public:
vector<bool> distanceLimitedPathsExist(int n, vector<vector<int>>& edgeList, vector<vector<int>>& queries) {
dsu u(n);
vector<bool> ans(queries.size(), false);
vector<int> q_id(queries.size());
iota(q_id.begin(), q_id.end(), 0); //生成 0,1,2,3...
sort(q_id.begin(), q_id.end(),[&](auto& a, auto& b){
return queries[a][2] < queries[b][2];//對查詢的id排序,距離小的先查詢
});
sort(edgeList.begin(), edgeList.end(),[&](auto& a, auto& b){
return a[2] < b[2];//邊短的先加入並查集合並
});
int j = 0, limit;
for(int i = 0; i < q_id.size(); ++i)
{
limit = queries[q_id[i]][2];
while(j < edgeList.size() && edgeList[j][2] < limit)//距離滿足要求
{
u.merge(edgeList[j][0], edgeList[j][1]);//合併兩點
j++;
}
if(u.find(queries[q_id[i]][0]) == u.find(queries[q_id[i]][1]))
ans[q_id[i]] = true;
}
return ans;
}
};
我的CSDN部落格地址 https://michael.blog.csdn.net/
長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!