1. 程式人生 > 其它 >LeetCode 5632. 檢查邊長度限制的路徑是否存在(排序+並查集)

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

,當 queries[j] 的查詢結果為 true 時, answer 第 j 個值為 true ,否則為 false 。

示例 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]
解釋:上圖為給定的輸入資料。注意到 01 之間有兩條重邊,分別為 216 。
對於第一個查詢,01 之間沒有小於 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阿明),一起加油、一起學習進步!
Michael阿明