{"id":7830,"date":"2020-12-20T02:00:20","date_gmt":"2020-12-20T10:00:20","guid":{"rendered":"https:\/\/zxi.mytechroad.com\/blog\/?p=7830"},"modified":"2020-12-22T22:34:03","modified_gmt":"2020-12-23T06:34:03","slug":"leetcode-1697-checking-existence-of-edge-length-limited-paths","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/graph\/leetcode-1697-checking-existence-of-edge-length-limited-paths\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 1697. Checking Existence of Edge Length Limited Paths"},"content":{"rendered":"\n<p>An undirected graph of&nbsp;<code>n<\/code>&nbsp;nodes is defined by&nbsp;<code>edgeList<\/code>, where&nbsp;<code>edgeList[i] = [u<sub>i<\/sub>, v<sub>i<\/sub>, dis<sub>i<\/sub>]<\/code>&nbsp;denotes an edge between nodes&nbsp;<code>u<sub>i<\/sub><\/code>&nbsp;and&nbsp;<code>v<sub>i<\/sub><\/code>&nbsp;with distance&nbsp;<code>dis<sub>i<\/sub><\/code>. Note that there may be&nbsp;<strong>multiple<\/strong>&nbsp;edges between two nodes.<\/p>\n\n\n\n<p>Given an array&nbsp;<code>queries<\/code>, where&nbsp;<code>queries[j] = [p<sub>j<\/sub>, q<sub>j<\/sub>, limit<sub>j<\/sub>]<\/code>, your task is to determine for each&nbsp;<code>queries[j]<\/code>&nbsp;whether there is a path between&nbsp;<code>p<sub>j<\/sub><\/code>&nbsp;and&nbsp;<code>q<sub>j<\/sub><\/code>such that each edge on the path has a distance&nbsp;<strong>strictly less than<\/strong>&nbsp;<code>limit<sub>j<\/sub><\/code>&nbsp;.<\/p>\n\n\n\n<p>Return&nbsp;<em>a&nbsp;<strong>boolean array<\/strong>&nbsp;<\/em><code>answer<\/code><em>, where&nbsp;<\/em><code>answer.length == queries.length<\/code>&nbsp;<em>and the&nbsp;<\/em><code>j<sup>th<\/sup><\/code>&nbsp;<em>value of&nbsp;<\/em><code>answer<\/code>&nbsp;<em>is&nbsp;<\/em><code>true<\/code><em>&nbsp;if there is a path for&nbsp;<\/em><code>queries[j]<\/code><em>&nbsp;is&nbsp;<\/em><code>true<\/code><em>, and&nbsp;<\/em><code>false<\/code><em>&nbsp;otherwise<\/em>.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2020\/12\/08\/h.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> n = 3, edgeList = [[0,1,2],[1,2,4],[2,0,8],[1,0,16]], queries = [[0,1,2],[0,2,5]]\n<strong>Output:<\/strong> [false,true]\n<strong>Explanation:<\/strong> The above figure shows the given graph. Note that there are two overlapping edges between 0 and 1 with distances 2 and 16.\nFor the first query, between 0 and 1 there is no path where each distance is less than 2, thus we return false for this query.\nFor the second query, there is a path (0 -&gt; 1 -&gt; 2) of two edges with distances less than 5, thus we return true for this query.\n<\/pre>\n\n\n\n<p><strong>Example 2:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2020\/12\/08\/q.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> n = 5, edgeList = [[0,1,10],[1,2,5],[2,3,9],[3,4,13]], queries = [[0,4,14],[1,4,13]]\n<strong>Output:<\/strong> [true,false]\n<strong>Exaplanation:<\/strong> The above figure shows the given graph.\n<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>2 &lt;= n &lt;= 10<sup>5<\/sup><\/code><\/li><li><code>1 &lt;= edgeList.length, queries.length &lt;= 10<sup>5<\/sup><\/code><\/li><li><code>edgeList[i].length == 3<\/code><\/li><li><code>queries[j].length == 3<\/code><\/li><li><code>0 &lt;= u<sub>i<\/sub>, v<sub>i<\/sub>, p<sub>j<\/sub>, q<sub>j<\/sub>&nbsp;&lt;= n - 1<\/code><\/li><li><code>u<sub>i<\/sub>&nbsp;!= v<sub>i<\/sub><\/code><\/li><li><code>p<sub>j<\/sub>&nbsp;!= q<sub>j<\/sub><\/code><\/li><li><code>1 &lt;= dis<sub>i<\/sub>, limit<sub>j<\/sub>&nbsp;&lt;= 10<sup>9<\/sup><\/code><\/li><li>There may be&nbsp;<strong>multiple<\/strong>&nbsp;edges between two nodes.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution: Union Find<\/strong><\/h2>\n\n\n\n<p>Since queries are offline, we can reorder them to optimize time complexity. Answer queries by their limits in ascending order while union edges by weights up to the limit. In this case, we just need to go through the entire edge list at most once.<\/p>\n\n\n\n<p>Time complexity: O(QlogQ + ElogE)<br>Space complexity: O(Q + E)<\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua\nclass Solution {\npublic:\n  vector<bool> distanceLimitedPathsExist(int n, vector<vector<int>>& E, vector<vector<int>>& Q) {\n    vector<int> parents(n);\n    iota(begin(parents), end(parents), 0);\n    function<int(int)> find = [&](int x) {\n      return parents[x] == x ? x : parents[x] = find(parents[x]);\n    };\n    const int m = Q.size();\n    for (int i = 0; i < m; ++i) Q[i].push_back(i);\n    \/\/ Sort edges by weight in ascending order.\n    sort(begin(E), end(E), [](const auto&#038; a, const auto&#038; b) { return a[2] < b[2]; });\n    \/\/ Sort queries by limit in ascending order\n    sort(begin(Q), end(Q), [](const auto&#038; a, const auto&#038; b) { return a[2] < b[2]; });\n    vector<bool> ans(m);\n    int i = 0;\n    for (const auto& q : Q) {      \n      while (i < E.size() &#038;&#038; E[i][2] < q[2])\n        parents[find(E[i++][0])] = find(E[i][1]);        \n      ans[q[3]] = find(q[0]) == find(q[1]);\n    }\n    return ans;\n  }\n};\n<\/pre>\n<\/div><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>An undirected graph of&nbsp;n&nbsp;nodes is defined by&nbsp;edgeList, where&nbsp;edgeList[i] = [ui, vi, disi]&nbsp;denotes an edge between nodes&nbsp;ui&nbsp;and&nbsp;vi&nbsp;with distance&nbsp;disi. Note that there may be&nbsp;multiple&nbsp;edges between two nodes.&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[77,217,15,113],"class_list":["post-7830","post","type-post","status-publish","format-standard","hentry","category-graph","tag-graph","tag-hard","tag-sorting","tag-union-find","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7830","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/comments?post=7830"}],"version-history":[{"count":3,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7830\/revisions"}],"predecessor-version":[{"id":7839,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7830\/revisions\/7839"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=7830"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=7830"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=7830"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}