<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>shortest path Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/shortest-path/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/shortest-path/</link>
	<description></description>
	<lastBuildDate>Mon, 08 Jan 2024 14:01:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>shortest path Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/shortest-path/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2976. Minimum Cost to Convert String I</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 08 Jan 2024 14:01:15 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10100</guid>

					<description><![CDATA[<p>You are given two&#160;0-indexed&#160;strings&#160;source&#160;and&#160;target, both of length&#160;n&#160;and consisting of&#160;lowercase&#160;English letters. You are also given two&#160;0-indexed&#160;character arrays&#160;original&#160;and&#160;changed, and an integer array&#160;cost, where&#160;cost[i]&#160;represents the cost of changing&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/">花花酱 LeetCode 2976. Minimum Cost to Convert String I</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given two&nbsp;<strong>0-indexed</strong>&nbsp;strings&nbsp;<code>source</code>&nbsp;and&nbsp;<code>target</code>, both of length&nbsp;<code>n</code>&nbsp;and consisting of&nbsp;<strong>lowercase</strong>&nbsp;English letters. You are also given two&nbsp;<strong>0-indexed</strong>&nbsp;character arrays&nbsp;<code>original</code>&nbsp;and&nbsp;<code>changed</code>, and an integer array&nbsp;<code>cost</code>, where&nbsp;<code>cost[i]</code>&nbsp;represents the cost of changing the character&nbsp;<code>original[i]</code>&nbsp;to the character&nbsp;<code>changed[i]</code>.</p>



<p>You start with the string&nbsp;<code>source</code>. In one operation, you can pick a character&nbsp;<code>x</code>&nbsp;from the string and change it to the character&nbsp;<code>y</code>&nbsp;at a cost of&nbsp;<code>z</code>&nbsp;<strong>if</strong>&nbsp;there exists&nbsp;<strong>any</strong>&nbsp;index&nbsp;<code>j</code>&nbsp;such that&nbsp;<code>cost[j] == z</code>,&nbsp;<code>original[j] == x</code>, and&nbsp;<code>changed[j] == y</code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;cost to convert the string&nbsp;</em><code>source</code><em>&nbsp;to the string&nbsp;</em><code>target</code><em>&nbsp;using&nbsp;<strong>any</strong>&nbsp;number of operations. If it is impossible to convert</em>&nbsp;<code>source</code>&nbsp;<em>to</em>&nbsp;<code>target</code>,&nbsp;<em>return</em>&nbsp;<code>-1</code>.</p>



<p><strong>Note</strong>&nbsp;that there may exist indices&nbsp;<code>i</code>,&nbsp;<code>j</code>&nbsp;such that&nbsp;<code>original[j] == original[i]</code>&nbsp;and&nbsp;<code>changed[j] == changed[i]</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "abcd", target = "acbe", original = ["a","b","c","c","e","d"], changed = ["b","c","b","e","b","e"], cost = [2,5,5,1,2,20]
<strong>Output:</strong> 28
<strong>Explanation:</strong> To convert the string "abcd" to string "acbe":
- Change value at index 1 from 'b' to 'c' at a cost of 5.
- Change value at index 2 from 'c' to 'e' at a cost of 1.
- Change value at index 2 from 'e' to 'b' at a cost of 2.
- Change value at index 3 from 'd' to 'e' at a cost of 20.
The total cost incurred is 5 + 1 + 2 + 20 = 28.
It can be shown that this is the minimum possible cost.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "aaaa", target = "bbbb", original = ["a","c"], changed = ["c","b"], cost = [1,2]
<strong>Output:</strong> 12
<strong>Explanation:</strong> To change the character 'a' to 'b' change the character 'a' to 'c' at a cost of 1, followed by changing the character 'c' to 'b' at a cost of 2, for a total cost of 1 + 2 = 3. To change all occurrences of 'a' to 'b', a total cost of 3 * 4 = 12 is incurred.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "abcd", target = "abce", original = ["a"], changed = ["e"], cost = [10000]
<strong>Output:</strong> -1
<strong>Explanation:</strong> It is impossible to convert source to target because the value at index 3 cannot be changed from 'd' to 'e'.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= source.length == target.length &lt;= 10<sup>5</sup></code></li><li><code>source</code>,&nbsp;<code>target</code>&nbsp;consist of lowercase English letters.</li><li><code>1 &lt;= cost.length == original.length == changed.length &lt;= 2000</code></li><li><code>original[i]</code>,&nbsp;<code>changed[i]</code>&nbsp;are lowercase English letters.</li><li><code>1 &lt;= cost[i] &lt;= 10<sup>6</sup></code></li><li><code>original[i] != changed[i]</code></li></ul>



<h2><strong>Solution: All pairs shortest path</strong></h2>



<p>Compute the shortest path (min cost) for any given letter pairs.</p>



<p>Time complexity: O(26^3 + m + n)<br>Space complexity: O(26^2)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution {
public:
    long long minimumCost(string s, string t, vector&lt;char&gt;&amp; o, vector&lt;char&gt;&amp; c, vector&lt;int&gt;&amp; cost) {
    const int n = c.size();
    vector&lt;vector&lt;int&gt;&gt; d(26, vector&lt;int&gt;(26, 1e9));
    for (int i = 0; i &lt; 26; ++i)
      d[i][i] = 0;
    for (int i = 0; i &lt; n; ++i)
      d[o[i] - 'a'][c[i] - 'a'] = min(d[o[i] - 'a'][c[i] - 'a'], cost[i]);
    for (int k = 0; k &lt; 26; ++k)
      for (int i = 0; i &lt; 26;++i)
        for (int j = 0; j &lt; 26; ++j)
          if (d[i][k] + d[k][j] &lt; d[i][j])
            d[i][j] = d[i][k] + d[k][j];
    long ans = 0;
    for (int i = 0; i &lt; s.size(); ++i) {
      if (d[s[i] - 'a'][t[i] - 'a'] &gt;= 1e9) return -1; 
      ans += d[s[i] - 'a'][t[i] - 'a'];
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/">花花酱 LeetCode 2976. Minimum Cost to Convert String I</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Apr 2023 18:03:03 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10044</guid>

					<description><![CDATA[<p>You are given an array&#160;start&#160;where&#160;start = [startX, startY]&#160;represents your initial position&#160;(startX, startY)&#160;in a 2D space. You are also given the array&#160;target&#160;where&#160;target = [targetX, targetY]&#160;represents your&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/">花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads - 刷题找工作 EP411" width="500" height="281" src="https://www.youtube.com/embed/oBtS4aAJDaA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div></figure>



<p>You are given an array&nbsp;<code>start</code>&nbsp;where&nbsp;<code>start = [startX, startY]</code>&nbsp;represents your initial position&nbsp;<code>(startX, startY)</code>&nbsp;in a 2D space. You are also given the array&nbsp;<code>target</code>&nbsp;where&nbsp;<code>target = [targetX, targetY]</code>&nbsp;represents your target position&nbsp;<code>(targetX, targetY)</code>.</p>



<p>The cost of going from a position&nbsp;<code>(x1, y1)</code>&nbsp;to any other position in the space&nbsp;<code>(x2, y2)</code>&nbsp;is&nbsp;<code>|x2 - x1| + |y2 - y1|</code>.</p>



<p>There are also some special roads. You are given a 2D array&nbsp;<code>specialRoads</code>&nbsp;where&nbsp;<code>specialRoads[i] = [x1<sub>i</sub>, y1<sub>i</sub>, x2<sub>i</sub>, y2<sub>i</sub>, cost<sub>i</sub>]</code>&nbsp;indicates that the&nbsp;<code>i<sup>th</sup></code>&nbsp;special road can take you from&nbsp;<code>(x1<sub>i</sub>, y1<sub>i</sub>)</code>&nbsp;to&nbsp;<code>(x2<sub>i</sub>, y2<sub>i</sub>)</code>&nbsp;with a cost equal to&nbsp;<code>cost<sub>i</sub></code>. You can use each special road any number of times.</p>



<p>Return&nbsp;<em>the minimum cost required to go from</em>&nbsp;<code>(startX, startY)</code>&nbsp;to&nbsp;<code>(targetX, targetY)</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> start = [1,1], target = [4,5], specialRoads = [[1,2,3,3,2],[3,4,4,5,1]]
<strong>Output:</strong> 5
<strong>Explanation:</strong> The optimal path from (1,1) to (4,5) is the following:
- (1,1) -&gt; (1,2). This move has a cost of |1 - 1| + |2 - 1| = 1.
- (1,2) -&gt; (3,3). This move uses the first special edge, the cost is 2.
- (3,3) -&gt; (3,4). This move has a cost of |3 - 3| + |4 - 3| = 1.
- (3,4) -&gt; (4,5). This move uses the second special edge, the cost is 1.
So the total cost is 1 + 2 + 1 + 1 = 5.
It can be shown that we cannot achieve a smaller total cost than 5.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> start = [3,2], target = [5,7], specialRoads = [[3,2,3,4,4],[3,3,5,5,5],[3,4,5,6,6]]
<strong>Output:</strong> 7
<strong>Explanation:</strong> It is optimal to not use any special edges and go directly from the starting to the ending position with a cost |5 - 3| + |7 - 2| = 7.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>start.length == target.length == 2</code></li><li><code>1 &lt;= startX &lt;= targetX &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= startY &lt;= targetY &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= specialRoads.length &lt;= 200</code></li><li><code>specialRoads[i].length == 5</code></li><li><code>startX &lt;= x1<sub>i</sub>, x2<sub>i</sub> &lt;= targetX</code></li><li><code>startY &lt;= y1<sub>i</sub>, y2<sub>i</sub> &lt;= targetY</code></li><li><code>1 &lt;= cost<sub>i</sub> &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Dijkstra</strong></h2>



<ol><li>Create a node for each point in special edges as well as start and target. </li><li>Add edges for special roads (note it&#8217;s directional)</li><li>Add edges for each pair of node with default cost, i.e. |x1-x2| + |y1-y2|</li><li>Run Dijkstra&#8217;s algorithm</li></ol>



<p>Time complexity: O(n<sup>2</sup>logn)<br>Space complexity: O(n<sup>2</sup>)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int minimumCost(vector&lt;int&gt;&amp; start, vector&lt;int&gt;&amp; target, vector&lt;vector&lt;int&gt;&gt;&amp; specialRoads) {
    unordered_map&lt;long, int&gt; ids;
    vector&lt;pair&lt;int, int&gt;&gt; pos;
    
    auto getId = [&amp;](int x, int y) {
      const auto key = ((unsigned long)x &lt;&lt; 32) | y;
      if (ids.count(key)) return ids[key];
      const int id = ids.size();      
      ids[key] = id;
      pos.emplace_back(x, y);
      return id;
    };
    const int s = getId(start[0], start[1]);
    const int t = getId(target[0], target[1]);
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g;
    auto addEdge = [&amp;](int x1, int y1, int x2, int y2, int c = INT_MAX) {      
      int n1 = getId(x1, y1);
      int n2 = getId(x2, y2);
      if (n1 == n2) return;
      while (g.size() &lt;= max(n1, n2)) g.push_back({});      
      int cost = min(c, abs(x1 - x2) + abs(y1 - y2));
      g[n1].emplace_back(cost, n2);
      // directional for special edge
      if (c == INT_MAX) g[n2].emplace_back(cost, n1);
    };
    for (const auto&amp; r : specialRoads)
      addEdge(r[0], r[1], r[2], r[3], r[4]);    
    for (int i = 0; i &lt; pos.size(); ++i)
      for (int j = i + 1; j &lt; pos.size(); ++j)
        addEdge(pos[i].first, pos[i].second, 
                pos[j].first, pos[j].second);
    vector&lt;int&gt; dist(ids.size(), INT_MAX);
    dist[s] = 0;
    priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, greater&lt;&gt;&gt; q;
    q.emplace(0, s);    
    while (!q.empty()) {
      auto [d, u] = q.top(); q.pop();
      if (d &gt; dist[u]) continue;
      if (u == t) return d;
      for (auto [c, v] : g[u])
        if (d + c &lt; dist[v])
          q.emplace(dist[v] = d + c, v);
    }
    return -1;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/">花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 29 Apr 2023 19:16:35 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[floyd-warshall]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10015</guid>

					<description><![CDATA[<p>There is a&#160;directed weighted&#160;graph that consists of&#160;n&#160;nodes numbered from&#160;0&#160;to&#160;n - 1. The edges of the graph are initially represented by the given array&#160;edges&#160;where&#160;edges[i] = [fromi,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/">花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There is a&nbsp;<strong>directed weighted</strong>&nbsp;graph that consists of&nbsp;<code>n</code>&nbsp;nodes numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. The edges of the graph are initially represented by the given array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>, edgeCost<sub>i</sub>]</code>&nbsp;meaning that there is an edge from&nbsp;<code>from<sub>i</sub></code>&nbsp;to&nbsp;<code>to<sub>i</sub></code>&nbsp;with the cost&nbsp;<code>edgeCost<sub>i</sub></code>.</p>



<p>Implement the&nbsp;<code>Graph</code>&nbsp;class:</p>



<ul><li><code>Graph(int n, int[][] edges)</code>&nbsp;initializes the object with&nbsp;<code>n</code>&nbsp;nodes and the given edges.</li><li><code>addEdge(int[] edge)</code>&nbsp;adds an edge to the list of edges where&nbsp;<code>edge = [from, to, edgeCost]</code>. It is guaranteed that there is no edge between the two nodes before adding this one.</li><li><code>int shortestPath(int node1, int node2)</code>&nbsp;returns the&nbsp;<strong>minimum</strong>&nbsp;cost of a path from&nbsp;<code>node1</code>&nbsp;to&nbsp;<code>node2</code>. If no path exists, return&nbsp;<code>-1</code>. The cost of a path is the sum of the costs of the edges in the path.</li></ul>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/01/11/graph3drawio-2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["Graph", "shortestPath", "shortestPath", "addEdge", "shortestPath"]
[[4, [[0, 2, 5], [0, 1, 2], [1, 2, 1], [3, 0, 3]]], [3, 2], [0, 3], [[1, 3, 4]], [0, 3]]
<strong>Output</strong>
[null, 6, -1, null, 6]
</pre>



<p><strong>Explanation</strong> </p>



<pre class="wp-block-preformatted;crayon:false">Graph g = new Graph(4, [[0, 2, 5], [0, 1, 2], [1, 2, 1], [3, 0, 3]]); g.shortestPath(3, 2); // return 6. The shortest path from 3 to 2 in the first diagram above is 3 -> 0 -> 1 -> 2 with a total cost of 3 + 2 + 1 = 6.
g.shortestPath(0, 3); // return -1. There is no path from 0 to 3. 
g.addEdge([1, 3, 4]); // We add an edge from node 1 to node 3, and we get the second diagram above. 
g.shortestPath(0, 3); // return 6. The shortest path from 0 to 3 now is 0 -> 1 -> 3 with a total cost of 2 + 4 = 6.</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 100</code></li><li><code>0 &lt;= edges.length &lt;= n * (n - 1)</code></li><li><code>edges[i].length == edge.length == 3</code></li><li><code>0 &lt;= from<sub>i</sub>, to<sub>i</sub>, from, to, node1, node2 &lt;= n - 1</code></li><li><code>1 &lt;= edgeCost<sub>i</sub>, edgeCost &lt;= 10<sup>6</sup></code></li><li>There are no repeated edges and no self-loops in the graph at any point.</li><li>At most&nbsp;<code>100</code>&nbsp;calls will be made for&nbsp;<code>addEdge</code>.</li><li>At most&nbsp;<code>100</code>&nbsp;calls will be made for&nbsp;<code>shortestPath</code>.</li></ul>



<h2><strong>Solution 1: Floyd-Washall</strong></h2>



<p>Time complexity:<br>Init O(n<sup>3</sup>)<br>addEdge O(n<sup>2</sup>)<br>shortestPath O(1)</p>



<p>Space complexity: O(1)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Graph {
public:
  Graph(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges):
  n_(n),
  d_(n, vector&lt;long&gt;(n, 1e18)) {
    for (int i = 0; i &lt; n; ++i)
      d_[i][i] = 0;
    for (const vector&lt;int&gt;&amp; e : edges)
      d_[e[0]][e[1]] = e[2];    
    for (int k = 0; k &lt; n; ++k)
      for (int i = 0; i &lt; n; ++i)
        for (int j = 0; j &lt; n; ++j)
          d_[i][j] = min(d_[i][j], d_[i][k] + d_[k][j]);
  }
  
  void addEdge(vector&lt;int&gt; edge) {    
    for (int i = 0; i &lt; n_; ++i)
      for (int j = 0; j &lt; n_; ++j)
        d_[i][j] = min(d_[i][j], d_[i][edge[0]] + edge[2] + d_[edge[1]][j]);
  }
  
  int shortestPath(int node1, int node2) {
    return d_[node1][node2] &gt;= 1e18 ? -1 : d_[node1][node2];
  }
private:
  int n_;
  vector&lt;vector&lt;long&gt;&gt; d_;
};</pre>
</div></div>



<h2><strong>Solution 2: Dijkstra</strong></h2>



<p>Time complexity: <br>Init: O(|E|) ~ O(n<sup>2</sup>)<br>AddEdge: O(1)<br>ShortestPath: O(|V|*log(|E|)) ~ O(n*logn)</p>



<p>Space complexity: O(E|) ~ O(n<sup>2</sup>)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Graph {
public:
    Graph(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges): n_(n), g_(n) {
      for (const auto&amp; e : edges)
        g_[e[0]].emplace_back(e[1], e[2]);
    }
    
    void addEdge(vector&lt;int&gt; edge) {
      g_[edge[0]].emplace_back(edge[1], edge[2]);
    }
    
    int shortestPath(int node1, int node2) {
      vector&lt;int&gt; dist(n_, INT_MAX);
      dist[node1] = 0;
      priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, greater&lt;&gt;&gt; q;
      q.emplace(0, node1);
      while (!q.empty()) {
        const auto [d, u] = q.top(); q.pop();        
        if (u == node2) return d;
        for (const auto&amp; [v, c] : g_[u])
          if (dist[u] + c &lt; dist[v]) {
            dist[v] = dist[u] + c;
            q.emplace(dist[v], v);
          }
      }
      return -1;
    }
private:
  int n_;
  vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g_;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/">花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2146. K Highest Ranked Items Within a Price Range</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 04 Feb 2022 01:23:04 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9458</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;2D integer array&#160;grid&#160;of size&#160;m x n&#160;that represents a map of the items in a shop. The integers in the grid represent the&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/">花花酱 LeetCode 2146. K Highest Ranked Items Within a Price Range</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>m x n</code>&nbsp;that represents a map of the items in a shop. The integers in the grid represent the following:</p>



<ul><li><code>0</code>&nbsp;represents a wall that you cannot pass through.</li><li><code>1</code>&nbsp;represents an empty cell that you can freely move to and from.</li><li>All other positive integers represent the price of an item in that cell. You may also freely move to and from these item cells.</li></ul>



<p>It takes&nbsp;<code>1</code>&nbsp;step to travel between adjacent grid cells.</p>



<p>You are also given integer arrays&nbsp;<code>pricing</code>&nbsp;and&nbsp;<code>start</code>&nbsp;where&nbsp;<code>pricing = [low, high]</code>&nbsp;and&nbsp;<code>start = [row, col]</code>&nbsp;indicates that you start at the position&nbsp;<code>(row, col)</code>&nbsp;and are interested only in items with a price in the range of&nbsp;<code>[low, high]</code>&nbsp;(<strong>inclusive</strong>). You are further given an integer&nbsp;<code>k</code>.</p>



<p>You are interested in the&nbsp;<strong>positions</strong>&nbsp;of the&nbsp;<code>k</code>&nbsp;<strong>highest-ranked</strong>&nbsp;items whose prices are&nbsp;<strong>within</strong>&nbsp;the given price range. The rank is determined by the&nbsp;<strong>first</strong>&nbsp;of these criteria that is different:</p>



<ol><li>Distance, defined as the length of the shortest path from the&nbsp;<code>start</code>&nbsp;(<strong>shorter</strong>&nbsp;distance has a higher rank).</li><li>Price (<strong>lower</strong>&nbsp;price has a higher rank, but it must be&nbsp;<strong>in the price range</strong>).</li><li>The row number (<strong>smaller</strong>&nbsp;row number has a higher rank).</li><li>The column number (<strong>smaller</strong>&nbsp;column number has a higher rank).</li></ol>



<p>Return&nbsp;<em>the&nbsp;</em><code>k</code><em>&nbsp;highest-ranked items within the price range&nbsp;<strong>sorted</strong>&nbsp;by their rank (highest to lowest)</em>. If there are fewer than&nbsp;<code>k</code>&nbsp;reachable items within the price range, return&nbsp;<em><strong>all</strong>&nbsp;of them</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/12/16/example1drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,2,0,1],[1,3,0,1],[0,2,5,1]], pricing = [2,5], start = [0,0], k = 3
<strong>Output:</strong> [[0,1],[1,1],[2,1]]
<strong>Explanation:</strong> You start at (0,0).
With a price range of [2,5], we can take items from (0,1), (1,1), (2,1) and (2,2).
The ranks of these items are:
- (0,1) with distance 1
- (1,1) with distance 2
- (2,1) with distance 3
- (2,2) with distance 4
Thus, the 3 highest ranked items in the price range are (0,1), (1,1), and (2,1).
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/12/16/example2drawio1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,2,0,1],[1,3,3,1],[0,2,5,1]], pricing = [2,3], start = [2,3], k = 2
<strong>Output:</strong> [[2,1],[1,2]]
<strong>Explanation:</strong> You start at (2,3).
With a price range of [2,3], we can take items from (0,1), (1,1), (1,2) and (2,1).
The ranks of these items are:
- (2,1) with distance 2, price 2
- (1,2) with distance 2, price 3
- (1,1) with distance 3
- (0,1) with distance 4
Thus, the 2 highest ranked items in the price range are (2,1) and (1,2).
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/12/30/example3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,1],[0,0,1],[2,3,4]], pricing = [2,3], start = [0,0], k = 3
<strong>Output:</strong> [[2,1],[2,0]]
<strong>Explanation:</strong> You start at (0,0).
With a price range of [2,3], we can take items from (2,0) and (2,1). 
The ranks of these items are: 
- (2,1) with distance 5
- (2,0) with distance 6
Thus, the 2 highest ranked items in the price range are (2,1) and (2,0). 
Note that k = 3 but there are only 2 reachable items within the price range.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= m * n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= grid[i][j] &lt;= 10<sup>5</sup></code></li><li><code>pricing.length == 2</code></li><li><code>2 &lt;= low &lt;= high &lt;= 10<sup>5</sup></code></li><li><code>start.length == 2</code></li><li><code>0 &lt;= row &lt;= m - 1</code></li><li><code>0 &lt;= col &lt;= n - 1</code></li><li><code>grid[row][col] &gt; 0</code></li><li><code>1 &lt;= k &lt;= m * n</code></li></ul>



<h2><strong>Solution: BFS + Sorting</strong></h2>



<p>Use BFS to collect reachable cells and sort afterwards.</p>



<p>Time complexity: O(mn + KlogK) where K = # of reachable cells.</p>



<p>Space complexity: O(mn)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; highestRankedKItems(vector&lt;vector&lt;int&gt;&gt;&amp; grid, vector&lt;int&gt;&amp; pricing, vector&lt;int&gt;&amp; start, int k) {
    const int m = grid.size();
    const int n = grid[0].size();    
    const vector&lt;int&gt; dirs{1, 0, -1, 0, 1};    
    vector&lt;vector&lt;int&gt;&gt; seen(m, vector&lt;int&gt;(n));
    seen[start[0]][start[1]] = 1;
    vector&lt;vector&lt;int&gt;&gt; cells;
    queue&lt;array&lt;int, 3&gt;&gt; q;
    q.push({start[0], start[1], 0});
    while (!q.empty()) {
      auto [y, x, d] = q.front(); q.pop();
      if (grid[y][x] &gt;= pricing[0] &amp;&amp; grid[y][x] &lt;= pricing[1])
          cells.push_back({d, grid[y][x], y, x});
      for (int i = 0; i &lt; 4; ++i) {
        const int tx = x + dirs[i];
        const int ty = y + dirs[i + 1];
        if (tx &lt; 0 || tx &gt;= n || ty &lt; 0 || ty &gt;= m 
            || !grid[ty][tx] || seen[ty][tx]++) continue;
        q.push({ty, tx, d + 1});
      }
    }
    sort(begin(cells), end(cells), less&lt;vector&lt;int&gt;&gt;());
    vector&lt;vector&lt;int&gt;&gt; ans;
    for (int i = 0; i &lt; min(k, (int)(cells.size())); ++i)
      ans.push_back({cells[i][2], cells[i][3]});
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/">花花酱 LeetCode 2146. K Highest Ranked Items Within a Price Range</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1926. Nearest Exit from Entrance in Maze</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 30 Dec 2021 11:07:41 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9285</guid>

					<description><![CDATA[<p>You are given an&#160;m x n&#160;matrix&#160;maze&#160;(0-indexed) with empty cells (represented as&#160;'.') and walls (represented as&#160;'+'). You are also given the&#160;entrance&#160;of the maze, where&#160;entrance = [entrancerow,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/">花花酱 LeetCode 1926. Nearest Exit from Entrance in Maze</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given an&nbsp;<code>m x n</code>&nbsp;matrix&nbsp;<code>maze</code>&nbsp;(<strong>0-indexed</strong>) with empty cells (represented as&nbsp;<code>'.'</code>) and walls (represented as&nbsp;<code>'+'</code>). You are also given the&nbsp;<code>entrance</code>&nbsp;of the maze, where&nbsp;<code>entrance = [entrance<sub>row</sub>, entrance<sub>col</sub>]</code>&nbsp;denotes the row and column of the cell you are initially standing at.</p>



<p>In one step, you can move one cell&nbsp;<strong>up</strong>,&nbsp;<strong>down</strong>,&nbsp;<strong>left</strong>, or&nbsp;<strong>right</strong>. You cannot step into a cell with a wall, and you cannot step outside the maze. Your goal is to find the&nbsp;<strong>nearest exit</strong>&nbsp;from the&nbsp;<code>entrance</code>. An&nbsp;<strong>exit</strong>&nbsp;is defined as an&nbsp;<strong>empty cell</strong>&nbsp;that is at the&nbsp;<strong>border</strong>&nbsp;of the&nbsp;<code>maze</code>. The&nbsp;<code>entrance</code>&nbsp;<strong>does not count</strong>&nbsp;as an exit.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>number of steps</strong>&nbsp;in the shortest path from the&nbsp;</em><code>entrance</code><em>&nbsp;to the nearest exit, or&nbsp;</em><code>-1</code><em>&nbsp;if no such path exists</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/06/04/nearest1-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [["+","+",".","+"],[".",".",".","+"],["+","+","+","."]], entrance = [1,2]
<strong>Output:</strong> 1
<strong>Explanation:</strong> There are 3 exits in this maze at [1,0], [0,2], and [2,3].
Initially, you are at the entrance cell [1,2].
- You can reach [1,0] by moving 2 steps left.
- You can reach [0,2] by moving 1 step up.
It is impossible to reach [2,3] from the entrance.
Thus, the nearest exit is [0,2], which is 1 step away.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/06/04/nearesr2-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [["+","+","+"],[".",".","."],["+","+","+"]], entrance = [1,0]
<strong>Output:</strong> 2
<strong>Explanation:</strong> There is 1 exit in this maze at [1,2].
[1,0] does not count as an exit since it is the entrance cell.
Initially, you are at the entrance cell [1,0].
- You can reach [1,2] by moving 2 steps right.
Thus, the nearest exit is [1,2], which is 2 steps away.
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/06/04/nearest3-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [[".","+"]], entrance = [0,0]
<strong>Output:</strong> -1
<strong>Explanation:</strong> There are no exits in this maze.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>maze.length == m</code></li><li><code>maze[i].length == n</code></li><li><code>1 &lt;= m, n &lt;= 100</code></li><li><code>maze[i][j]</code>&nbsp;is either&nbsp;<code>'.'</code>&nbsp;or&nbsp;<code>'+'</code>.</li><li><code>entrance.length == 2</code></li><li><code>0 &lt;= entrance<sub>row</sub>&nbsp;&lt; m</code></li><li><code>0 &lt;= entrance<sub>col</sub>&nbsp;&lt; n</code></li><li><code>entrance</code>&nbsp;will always be an empty cell.</li></ul>



<h2><strong>Solution: BFS</strong></h2>



<p>Use BFS to find the shortest path. We can re-use the board for visited array.</p>



<p>Time complexity: O(m*n)<br>Space complexity: O(1)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int nearestExit(vector&lt;vector&lt;char&gt;&gt;&amp; maze, vector&lt;int&gt;&amp; entrance) {    
    const int m = maze.size();
    const int n = maze[0].size();
    const vector&lt;int&gt; dirs{0, -1, 0, 1, 0};
    queue&lt;pair&lt;int, int&gt;&gt; q;
    q.emplace(entrance[1], entrance[0]);    
    for (int steps = 0; !q.empty(); ++steps) {      
      for (int s = q.size(); s; --s) {      
        const auto [x, y] = q.front(); q.pop();        
        if (x == 0 || x == n - 1 || y == 0 || y == m - 1)
          if (x != entrance[1] || y != entrance[0])
            return steps;
        for (int i = 0; i &lt; 4; ++i) {
          const int tx = x + dirs[i];
          const int ty = y + dirs[i + 1];
          if (tx &lt; 0 || tx &gt;= n || ty &lt; 0 || ty &gt;= m || maze[ty][tx] != '.') continue;
          maze[ty][tx] = '*';
          q.emplace(tx, ty);
        }
      }      
    }
    return -1;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/">花花酱 LeetCode 1926. Nearest Exit from Entrance in Maze</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Dec 2021 08:11:36 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[LCA]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[shortest path]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9023</guid>

					<description><![CDATA[<p>You are given the&#160;root&#160;of a&#160;binary tree&#160;with&#160;n&#160;nodes. Each node is uniquely assigned a value from&#160;1&#160;to&#160;n. You are also given an integer&#160;startValue&#160;representing the value of the start&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/">花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given the&nbsp;<code>root</code>&nbsp;of a&nbsp;<strong>binary tree</strong>&nbsp;with&nbsp;<code>n</code>&nbsp;nodes. Each node is uniquely assigned a value from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. You are also given an integer&nbsp;<code>startValue</code>&nbsp;representing the value of the start node&nbsp;<code>s</code>, and a different integer&nbsp;<code>destValue</code>&nbsp;representing the value of the destination node&nbsp;<code>t</code>.</p>



<p>Find the&nbsp;<strong>shortest path</strong>&nbsp;starting from node&nbsp;<code>s</code>&nbsp;and ending at node&nbsp;<code>t</code>. Generate step-by-step directions of such path as a string consisting of only the&nbsp;<strong>uppercase</strong>&nbsp;letters&nbsp;<code>'L'</code>,&nbsp;<code>'R'</code>, and&nbsp;<code>'U'</code>. Each letter indicates a specific direction:</p>



<ul><li><code>'L'</code>&nbsp;means to go from a node to its&nbsp;<strong>left child</strong>&nbsp;node.</li><li><code>'R'</code>&nbsp;means to go from a node to its&nbsp;<strong>right child</strong>&nbsp;node.</li><li><code>'U'</code>&nbsp;means to go from a node to its&nbsp;<strong>parent</strong>&nbsp;node.</li></ul>



<p>Return&nbsp;<em>the step-by-step directions of the&nbsp;<strong>shortest path</strong>&nbsp;from node&nbsp;</em><code>s</code><em>&nbsp;to node</em>&nbsp;<code>t</code>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/11/15/eg1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6
<strong>Output:</strong> "UURL"
<strong>Explanation:</strong> The shortest path is: 3 → 1 → 5 → 2 → 6.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/11/15/eg2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [2,1], startValue = 2, destValue = 1
<strong>Output:</strong> "L"
<strong>Explanation:</strong> The shortest path is: 2 → 1.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li>The number of nodes in the tree is&nbsp;<code>n</code>.</li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= Node.val &lt;= n</code></li><li>All the values in the tree are&nbsp;<strong>unique</strong>.</li><li><code>1 &lt;= startValue, destValue &lt;= n</code></li><li><code>startValue != destValue</code></li></ul>



<h2><strong>Solution: Lowest common ancestor</strong></h2>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png" alt="" class="wp-image-9028" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>It&#8217;s no hard to see that the shortest path is from the start node to the lowest common ancestor (LCA) of (start, end), then to the end node. The key is to find the LCA while finding paths from root to two nodes.</p>



<p>We can use recursion to find/build a path from root to a target node.<br>The common prefix of these two paths is the path from root to the LCA that we need to remove from the shortest path.<br>e.g. <br>root to start &#8220;LLRLR&#8221;<br>root to dest &#8220;LLLR&#8221;<br>common prefix is &#8220;LL&#8221;, after removing, it becomes:<br>LCA to start &#8220;RLR&#8221;<br>LCA to dest &#8220;LR&#8221;<br>Final path becomes &#8220;UUU&#8221; + &#8220;LR&#8221; = &#8220;UUULR&#8221;</p>



<p>The final step is to replace the L/R with U for the start path since we are moving up and then concatenate with the target path.</p>



<p>Time complexity: O(n)<br>Space complexity: O(n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  string getDirections(TreeNode* root, int startValue, int destValue) {
    string startPath;
    string destPath;
    buildPath(root, startValue, startPath);
    buildPath(root, destValue, destPath);    
    // Remove common suffix (shared path from root to LCA)
    while (!startPath.empty() &amp;&amp; !destPath.empty() 
           &amp;&amp; startPath.back() == destPath.back()) {
      startPath.pop_back();
      destPath.pop_back();
    }
    reverse(begin(destPath), end(destPath));
    return string(startPath.size(), 'U') + destPath;
  }
private:
  bool buildPath(TreeNode* root, int t, string&amp; path) {
    if (!root) return false;
    if (root-&gt;val == t) return true;
    if (buildPath(root-&gt;left, t, path)) {
      path.push_back('L');
      return true;
    } else if (buildPath(root-&gt;right, t, path)) {
      path.push_back('R');
      return true;
    }
    return false;
  }
};</pre>
</div></div>



<p><br>  </p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/">花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2039. The Time When the Network Becomes Idle</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 19 Oct 2021 04:53:38 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8623</guid>

					<description><![CDATA[<p>There is a network of&#160;n&#160;servers, labeled from&#160;0&#160;to&#160;n - 1. You are given a 2D integer array&#160;edges, where&#160;edges[i] = [ui, vi]&#160;indicates there is a message channel&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/">花花酱 LeetCode 2039. The Time When the Network Becomes Idle</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There is a network of&nbsp;<code>n</code>&nbsp;servers, labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. You are given a 2D integer array&nbsp;<code>edges</code>, where&nbsp;<code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code>&nbsp;indicates there is a message channel between servers&nbsp;<code>u<sub>i</sub></code>&nbsp;and&nbsp;<code>v<sub>i</sub></code>, and they can pass&nbsp;<strong>any</strong>&nbsp;number of messages to&nbsp;<strong>each other</strong>&nbsp;directly in&nbsp;<strong>one</strong>&nbsp;second. You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>patience</code>&nbsp;of length&nbsp;<code>n</code>.</p>



<p>All servers are&nbsp;<strong>connected</strong>, i.e., a message can be passed from one server to any other server(s) directly or indirectly through the message channels.</p>



<p>The server labeled&nbsp;<code>0</code>&nbsp;is the&nbsp;<strong>master</strong>&nbsp;server. The rest are&nbsp;<strong>data</strong>&nbsp;servers. Each data server needs to send its message to the master server for processing and wait for a reply. Messages move between servers&nbsp;<strong>optimally</strong>, so every message takes the&nbsp;<strong>least amount of time</strong>&nbsp;to arrive at the master server. The master server will process all newly arrived messages&nbsp;<strong>instantly</strong>&nbsp;and send a reply to the originating server via the&nbsp;<strong>reversed path</strong>&nbsp;the message had gone through.</p>



<p>At the beginning of second&nbsp;<code>0</code>, each data server sends its message to be processed. Starting from second&nbsp;<code>1</code>, at the&nbsp;<strong>beginning</strong>&nbsp;of&nbsp;<strong>every</strong>&nbsp;second, each data server will check if it has received a reply to the message it sent (including any newly arrived replies) from the master server:</p>



<ul><li>If it has not, it will&nbsp;<strong>resend</strong>&nbsp;the message periodically. The data server&nbsp;<code>i</code>&nbsp;will resend the message every&nbsp;<code>patience[i]</code>&nbsp;second(s), i.e., the data server&nbsp;<code>i</code>&nbsp;will resend the message if&nbsp;<code>patience[i]</code>&nbsp;second(s) have&nbsp;<strong>elapsed</strong>&nbsp;since the&nbsp;<strong>last</strong>&nbsp;time the message was sent from this server.</li><li>Otherwise,&nbsp;<strong>no more resending</strong>&nbsp;will occur from this server.</li></ul>



<p>The network becomes&nbsp;<strong>idle</strong>&nbsp;when there are&nbsp;<strong>no</strong>&nbsp;messages passing between servers or arriving at servers.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>earliest second</strong>&nbsp;starting from which the network becomes&nbsp;<strong>idle</strong></em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/09/22/quiet-place-example1.png" alt="example 1"/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [[0,1],[1,2]], patience = [0,2,1]
<strong>Output:</strong> 8
<strong>Explanation:</strong>
At (the beginning of) second 0,
- Data server 1 sends its message (denoted 1A) to the master server.
- Data server 2 sends its message (denoted 2A) to the master server.

At second 1,
- Message 1A arrives at the master server. Master server processes message 1A instantly and sends a reply 1A back.
- Server 1 has not received any reply. 1 second (1 &lt; patience[1] = 2) elapsed since this server has sent the message, therefore it does not resend the message.
- Server 2 has not received any reply. 1 second (1 == patience[2] = 1) elapsed since this server has sent the message, therefore it resends the message (denoted 2B).

At second 2,
- The reply 1A arrives at server 1. No more resending will occur from server 1.
- Message 2A arrives at the master server. Master server processes message 2A instantly and sends a reply 2A back.
- Server 2 resends the message (denoted 2C).
...
At second 4,
- The reply 2A arrives at server 2. No more resending will occur from server 2.
...
At second 7, reply 2D arrives at server 2.

Starting from the beginning of the second 8, there are no messages passing between servers or arriving at servers.
This is the time when the network becomes idle.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/09/04/network_a_quiet_place_2.png" alt="example 2"/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [[0,1],[0,2],[1,2]], patience = [0,10,10]
<strong>Output:</strong> 3
<strong>Explanation:</strong> Data servers 1 and 2 receive a reply back at the beginning of second 2.
From the beginning of the second 3, the network becomes idle.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>n == patience.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>patience[0] == 0</code></li><li><code>1 &lt;= patience[i] &lt;= 10<sup>5</sup></code>&nbsp;for&nbsp;<code>1 &lt;= i &lt; n</code></li><li><code>1 &lt;= edges.length &lt;= min(10<sup>5</sup>, n * (n - 1) / 2)</code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= u<sub>i</sub>, v<sub>i</sub>&nbsp;&lt; n</code></li><li><code>u<sub>i</sub>&nbsp;!= v<sub>i</sub></code></li><li>There are no duplicate edges.</li><li>Each server can directly or indirectly reach another server.</li></ul>



<h2><strong>Solution: Shortest Path</strong></h2>



<p>Compute the shortest path from node 0 to rest of the nodes using BFS.</p>



<p>Idle time for node i = (dist[i] * 2 &#8211; 1) / patince[i] * patience[i] + dist[i] * 2 + 1</p>



<p>Time complexity: O(E + V)<br>Space complexity: O(E + V)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int networkBecomesIdle(vector&lt;vector&lt;int&gt;&gt;&amp; edges, vector&lt;int&gt;&amp; patience) {
    const int n = patience.size();
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }
    vector&lt;int&gt; ts(n, -1);
    ts[0] = 0;
    queue&lt;int&gt; q{{0}};    
    while (!q.empty()) {      
      int u = q.front(); q.pop();        
      for (int v : g[u]) {
        if (ts[v] != -1) continue;
        ts[v] = ts[u] + 1;
        q.push(v);
      }
    }
    int ans = 0;
    for (int i = 1; i &lt; n; ++i) {      
      int t = (ts[i] * 2 - 1) / patience[i] * patience[i] + ts[i] * 2 + 1;
      ans = max(ans, t);
    }    
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/">花花酱 LeetCode 2039. The Time When the Network Becomes Idle</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1786. Number of Restricted Paths From First to Last Node</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1786-number-of-restricted-paths-from-first-to-last-node/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1786-number-of-restricted-paths-from-first-to-last-node/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 07 Mar 2021 07:30:38 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8219</guid>

					<description><![CDATA[<p>There is an undirected weighted connected graph. You are given a positive integer&#160;n&#160;which denotes that the graph has&#160;n&#160;nodes labeled from&#160;1&#160;to&#160;n, and an array&#160;edges&#160;where each&#160;edges[i] =&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1786-number-of-restricted-paths-from-first-to-last-node/">花花酱 LeetCode 1786. Number of Restricted Paths From First to Last Node</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1786. Number of Restricted Paths From First to Last Node - 刷题找工作 EP388" width="500" height="281" src="https://www.youtube.com/embed/1VN6h1sohAs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>There is an undirected weighted connected graph. You are given a positive integer&nbsp;<code>n</code>&nbsp;which denotes that the graph has&nbsp;<code>n</code>&nbsp;nodes labeled from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>, and an array&nbsp;<code>edges</code>&nbsp;where each&nbsp;<code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>, weight<sub>i</sub>]</code>&nbsp;denotes that there is an edge between nodes&nbsp;<code>u<sub>i</sub></code>&nbsp;and&nbsp;<code>v<sub>i</sub></code>&nbsp;with weight equal to&nbsp;<code>weight<sub>i</sub></code>.</p>



<p>A path from node&nbsp;<code>start</code>&nbsp;to node&nbsp;<code>end</code>&nbsp;is a sequence of nodes&nbsp;<code>[z<sub>0</sub>, z<sub>1</sub>,z<sub>2</sub>, ..., z<sub>k</sub>]</code>&nbsp;such that&nbsp;<code>z<sub>0&nbsp;</sub>= start</code>&nbsp;and&nbsp;<code>z<sub>k</sub>&nbsp;= end</code>&nbsp;and there is an edge between&nbsp;<code>z<sub>i</sub></code>&nbsp;and&nbsp;<code>z<sub>i+1</sub></code>&nbsp;where&nbsp;<code>0 &lt;= i &lt;= k-1</code>.</p>



<p>The distance of a path is the sum of the weights on the edges of the path. Let&nbsp;<code>distanceToLastNode(x)</code>&nbsp;denote the shortest distance of a path between node&nbsp;<code>n</code>&nbsp;and node&nbsp;<code>x</code>. A&nbsp;<strong>restricted path</strong>&nbsp;is a path that also satisfies that&nbsp;<code>distanceToLastNode(z<sub>i</sub>) &gt; distanceToLastNode(z<sub>i+1</sub>)</code>&nbsp;where&nbsp;<code>0 &lt;= i &lt;= k-1</code>.</p>



<p>Return&nbsp;<em>the number of restricted paths from node</em>&nbsp;<code>1</code>&nbsp;<em>to node</em>&nbsp;<code>n</code>. Since that number may be too large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/02/17/restricted_paths_ex1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edges = [[1,2,3],[1,3,3],[2,3,1],[1,4,2],[5,2,2],[3,5,1],[5,4,10]]
<strong>Output:</strong> 3
<strong>Explanation:</strong> Each circle contains the node number in black and its <code>distanceToLastNode value in blue. </code>The three restricted paths are:
1) 1 --&gt; 2 --&gt; 5
2) 1 --&gt; 2 --&gt; 3 --&gt; 5
3) 1 --&gt; 3 --&gt; 5
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/02/17/restricted_paths_ex22.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[1,3,1],[4,1,2],[7,3,4],[2,5,3],[5,6,1],[6,7,2],[7,5,3],[2,6,4]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> Each circle contains the node number in black and its <code>distanceToLastNode value in blue. </code>The only restricted path is 1 --&gt; 3 --&gt; 7.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 2 * 10<sup>4</sup></code></li><li><code>n - 1 &lt;= edges.length &lt;= 4 * 10<sup>4</sup></code></li><li><code>edges[i].length == 3</code></li><li><code>1 &lt;= u<sub>i</sub>, v<sub>i</sub>&nbsp;&lt;= n</code></li><li><code>u<sub>i&nbsp;</sub>!= v<sub>i</sub></code></li><li><code>1 &lt;= weight<sub>i</sub>&nbsp;&lt;= 10<sup>5</sup></code></li><li>There is at most one edge between any two nodes.</li><li>There is at least one path between any two nodes.</li></ul>



<h2><strong>Solution: Dijkstra + DFS w/ memoization</strong></h2>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-1.png" alt="" class="wp-image-8225" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Find shortest path from n to all the nodes.<br>paths(u) = sum(paths(v)) if dist[u] &gt; dist[v] and (u, v) has an edge<br>return paths(1)</p>



<p>Time complexity: O(ElogV + V + E)<br>Space complexity: O(V + E)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int countRestrictedPaths(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    constexpr int kMod = 1e9 + 7;
    using PII = pair&lt;int, int&gt;;    
    vector&lt;vector&lt;PII&gt;&gt; g(n + 1);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }    
    
    // Shortest distance from n to x.
    vector&lt;int&gt; dist(n + 1, INT_MAX / 2);
    dist[n] = 0;
    priority_queue&lt;PII, vector&lt;PII&gt;, std::greater&lt;PII&gt;&gt; q;
    q.emplace(0, n);
    while (!q.empty()) {
      const auto [d, u] = q.top(); q.pop();
      if (dist[u] &lt; d) continue;
      for (auto [v, w]: g[u]) {
        if (dist[u] + w &gt;= dist[v]) continue;
        dist[v] = dist[u] + w;
        q.emplace(dist[v], v);
      }
    }

    vector&lt;int&gt; dp(n + 1, INT_MAX);
    function&lt;int(int)&gt; dfs = [&amp;](int u) {      
      if (u == n) return 1;
      if (dp[u] != INT_MAX) return dp[u];
      int ans = 0;
      for (auto [v, w]: g[u])
        if (dist[u] &gt; dist[v])
          ans = (ans + dfs(v)) % kMod;      
      return dp[u] = ans;
    };
    
    return dfs(1);
  }
};</pre>
</div></div>



<p>Combined</p>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-2.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-2.png" alt="" class="wp-image-8226" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-3.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-3.png" alt="" class="wp-image-8227" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1786-ep388-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int countRestrictedPaths(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    constexpr int kMod = 1e9 + 7;
    using PII = pair&lt;int, int&gt;;    
    vector&lt;vector&lt;PII&gt;&gt; g(n + 1);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }    
    
    // Shortest distance from n to x.
    vector&lt;int&gt; dist(n + 1, INT_MAX);
    vector&lt;int&gt; dp(n + 1);
    dist[n] = 0;
    dp[n] = 1;
    priority_queue&lt;PII, vector&lt;PII&gt;, std::greater&lt;PII&gt;&gt; q;
    q.emplace(0, n);
    while (!q.empty()) {
      const auto [d, u] = q.top(); q.pop();
      if (d &gt; dist[u]) continue;
      if (u == 1) break;
      for (auto [v, w]: g[u]) {
        if (dist[v] &gt; dist[u] + w)
          q.emplace(dist[v] = dist[u] + w, v);
        if (dist[v] &gt; dist[u])
          dp[v] = (dp[v] + dp[u]) % kMod;
      }
    }    
    return dp[1];
  }
};</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1786-number-of-restricted-paths-from-first-to-last-node/">花花酱 LeetCode 1786. Number of Restricted Paths From First to Last Node</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1786-number-of-restricted-paths-from-first-to-last-node/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1765. Map of Highest Peak</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 21 Feb 2021 05:19:36 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8135</guid>

					<description><![CDATA[<p>You are given an integer matrix&#160;isWater&#160;of size&#160;m x n&#160;that represents a map of&#160;land&#160;and&#160;water&#160;cells. If&#160;isWater[i][j] == 0, cell&#160;(i, j)&#160;is a&#160;land&#160;cell. If&#160;isWater[i][j] == 1, cell&#160;(i, j)&#160;is a&#160;water&#160;cell.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/">花花酱 LeetCode 1765. Map of Highest Peak</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given an integer matrix&nbsp;<code>isWater</code>&nbsp;of size&nbsp;<code>m x n</code>&nbsp;that represents a map of&nbsp;<strong>land</strong>&nbsp;and&nbsp;<strong>water</strong>&nbsp;cells.</p>



<ul><li>If&nbsp;<code>isWater[i][j] == 0</code>, cell&nbsp;<code>(i, j)</code>&nbsp;is a&nbsp;<strong>land</strong>&nbsp;cell.</li><li>If&nbsp;<code>isWater[i][j] == 1</code>, cell&nbsp;<code>(i, j)</code>&nbsp;is a&nbsp;<strong>water</strong>&nbsp;cell.</li></ul>



<p>You must assign each cell a height in a way that follows these rules:</p>



<ul><li>The height of each cell must be non-negative.</li><li>If the cell is a&nbsp;<strong>water</strong>&nbsp;cell, its height must be&nbsp;<code>0</code>.</li><li>Any two adjacent cells must have an absolute height difference of&nbsp;<strong>at most</strong>&nbsp;<code>1</code>. A cell is adjacent to another cell if the former is directly north, east, south, or west of the latter (i.e., their sides are touching).</li></ul>



<p>Find an assignment of heights such that the maximum height in the matrix is&nbsp;<strong>maximized</strong>.</p>



<p>Return&nbsp;<em>an integer matrix&nbsp;</em><code>height</code><em>&nbsp;of size&nbsp;</em><code>m x n</code><em>&nbsp;where&nbsp;</em><code>height[i][j]</code><em>&nbsp;is cell&nbsp;</em><code>(i, j)</code><em>&#8216;s height. If there are multiple solutions, return&nbsp;<strong>any</strong>&nbsp;of them</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/01/10/screenshot-2021-01-11-at-82045-am.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> isWater = [[0,1],[0,0]]
<strong>Output:</strong> [[1,0],[2,1]]
<strong>Explanation:</strong> The image shows the assigned heights of each cell.
The blue cell is the water cell, and the green cells are the land cells.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/01/10/screenshot-2021-01-11-at-82050-am.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> isWater = [[0,0,1],[1,0,0],[0,0,0]]
<strong>Output:</strong> [[1,1,0],[0,1,1],[1,2,2]]
<strong>Explanation:</strong> A height of 2 is the maximum possible height of any assignment.
Any height assignment that has a maximum height of 2 while still meeting the rules will also be accepted.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>m == isWater.length</code></li><li><code>n == isWater[i].length</code></li><li><code>1 &lt;= m, n &lt;= 1000</code></li><li><code>isWater[i][j]</code>&nbsp;is&nbsp;<code>0</code>&nbsp;or&nbsp;<code>1</code>.</li><li>There is at least&nbsp;<strong>one</strong>&nbsp;water cell.</li></ul>



<h2><strong>Solution: BFS</strong></h2>



<p>h[y][x] = min distance of (x, y) to any water cell.</p>



<p>Time complexity: O(m*n)<br>Space complexity: O(m*n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; highestPeak(vector&lt;vector&lt;int&gt;&gt;&amp; isWater) {
    const int m = isWater.size();
    const int n = isWater[0].size();
    vector&lt;vector&lt;int&gt;&gt; ans(m, vector&lt;int&gt;(n, INT_MIN));
    queue&lt;pair&lt;int, int&gt;&gt; q;
    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        if (isWater[y][x]) {
          q.emplace(x, y);
          ans[y][x] = 0;
        }
    const vector&lt;int&gt; dirs{0, -1, 0, 1, 0};    
    while (!q.empty()) {
      const auto [cx, cy] = q.front();
      q.pop();
      for (int i = 0; i &lt; 4; ++i) {
        const int x = cx + dirs[i];
        const int y = cy + dirs[i + 1];
        if (x &lt; 0 || x &gt;= n || y &lt; 0 || y &gt;= m) continue;
        if (ans[y][x] != INT_MIN) continue;
        ans[y][x] = ans[cy][cx] + 1;
        q.emplace(x, y);
      }      
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/">花花酱 LeetCode 1765. Map of Highest Peak</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1514. Path with Maximum Probability</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1514-path-with-maximum-probability/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1514-path-with-maximum-probability/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Jul 2020 05:44:28 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7079</guid>

					<description><![CDATA[<p>You are given an undirected weighted graph of&#160;n&#160;nodes (0-indexed), represented by an edge list where&#160;edges[i] = [a, b]&#160;is an undirected edge connecting the nodes&#160;a&#160;and&#160;b&#160;with a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1514-path-with-maximum-probability/">花花酱 LeetCode 1514. Path with Maximum Probability</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given an undirected weighted graph of&nbsp;<code>n</code>&nbsp;nodes (0-indexed), represented by an edge list where&nbsp;<code>edges[i] = [a, b]</code>&nbsp;is an undirected edge connecting the nodes&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>&nbsp;with a probability of success of traversing that edge&nbsp;<code>succProb[i]</code>.</p>



<p>Given two nodes&nbsp;<code>start</code>&nbsp;and&nbsp;<code>end</code>, find the path with the maximum probability of success to go from&nbsp;<code>start</code>&nbsp;to&nbsp;<code>end</code>&nbsp;and return its success probability.</p>



<p>If there is no path from&nbsp;<code>start</code>&nbsp;to&nbsp;<code>end</code>,&nbsp;<strong>return&nbsp;0</strong>. Your answer will be accepted if it differs from the correct answer by at most&nbsp;<strong>1e-5</strong>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/09/20/1558_ex1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
<strong>Output:</strong> 0.25000
<strong>Explanation:</strong>&nbsp;There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/09/20/1558_ex2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
<strong>Output:</strong> 0.30000
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/09/20/1558_ex3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
<strong>Output:</strong> 0.00000
<strong>Explanation:</strong>&nbsp;There is no path between 0 and 2.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>2 &lt;= n &lt;= 10^4</code></li><li><code>0 &lt;= start, end &lt; n</code></li><li><code>start != end</code></li><li><code>0 &lt;= a, b &lt; n</code></li><li><code>a != b</code></li><li><code>0 &lt;= succProb.length == edges.length &lt;= 2*10^4</code></li><li><code>0 &lt;= succProb[i] &lt;= 1</code></li><li>There is at most one edge between every two nodes.</li></ul>



<h2><strong>Solution: Dijkstra&#8217;s Algorithm</strong></h2>



<p>max(P1*P2*&#8230;*Pn) =&gt; max(log(P1*P2&#8230;*Pn)) =&gt; max(log(P1) + log(P2) + &#8230; + log(Pn) =&gt; min(-(log(P1) + log(P2) &#8230; + log(Pn)).</p>



<p>Thus we can convert this problem to the classic single source shortest path problem that can be solved with Dijkstra&#8217;s algorithm.</p>



<p>Time complexity: O(ElogV)<br>Space complexity: O(E+V)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
// Author: Huahua
class Solution {
public:
  double maxProbability(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges, 
                        vector&lt;double&gt;&amp; succProb, int start, int end) {
    vector&lt;vector&lt;pair&lt;int, double&gt;&gt;&gt; g(n); // u -&gt; {v, -log(w)}
    for (int i = 0; i &lt; edges.size(); ++i) {
      const double w = -log(succProb[i]);
      g[edges[i][0]].emplace_back(edges[i][1], w);
      g[edges[i][1]].emplace_back(edges[i][0], w);
    }

    vector&lt;double&gt; dist(n, FLT_MAX);
    priority_queue&lt;pair&lt;double, int&gt;&gt; q;
    q.emplace(-0.0, start);
    vector&lt;int&gt; seen(n);
    while (!q.empty()) {
      const double d = -q.top().first;
      const int u = q.top().second;        
      q.pop();
      seen[u] = 1;
      if (u == end) return exp(-d);
      for (const auto&amp; [v, w] : g[u]) {
        if (seen[v] || d + w &gt; dist[v]) continue;
        q.emplace(-(dist[v] = d + w), v);
      }
    }
    return 0;
  }
};</pre>

</div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
import java.util.AbstractMap;

class Solution {
  public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
    var g = new ArrayList&lt;List&lt;Map.Entry&lt;Integer, Double&gt;&gt;&gt;();
    for (int i = 0; i &lt; n; ++i) g.add(new ArrayList&lt;Map.Entry&lt;Integer, Double&gt;&gt;());
    for (int i = 0; i &lt; edges.length; ++i) {
      g.get(edges[i][0]).add(new AbstractMap.SimpleEntry&lt;&gt;(edges[i][1], -Math.log(succProb[i])));
      g.get(edges[i][1]).add(new AbstractMap.SimpleEntry&lt;&gt;(edges[i][0], -Math.log(succProb[i])));
    }    
    var seen = new boolean[n];
    var dist = new double[n];
    Arrays.fill(dist, Double.MAX_VALUE);
    seen[start] = true;
    dist[start] = 0.0;
    // {u, dist[u]}
    var q = new PriorityQueue&lt;Map.Entry&lt;Integer, Double&gt;&gt;(Map.Entry.comparingByValue());    
    q.offer(new AbstractMap.SimpleEntry&lt;&gt;(start, 0.0));
    while (!q.isEmpty()) {
      var node = q.poll();
      final int u = node.getKey();
      if (u == end) return Math.exp(-dist[end]);
      seen[u] = true;
      for (var e : g.get(u)) {
        final int v = e.getKey();
        final double w = e.getValue();
        if (seen[v] || dist[u] + w &gt; dist[v]) continue;
        dist[v] = dist[u] + w;
        q.offer(new AbstractMap.SimpleEntry&lt;&gt;(v, dist[v]));
      }
    }
    return 0;
  }
}</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def maxProbability(self, n: int, edges: List[List[int]], 
                     succProb: List[float], start: int, end: int) -&gt; float:
    g = [[] for _ in range(n)]
    for i, e in enumerate(edges):
      g[e[0]].append((e[1], -math.log(succProb[i])))
      g[e[1]].append((e[0], -math.log(succProb[i])))
    seen = [False] * n
    dist = [float('inf')] * n
    dist[start] = 0.0
    q = [(dist[start], start)]
    while q:
      _, u = heapq.heappop(q)
      if seen[u]: continue
      seen[u] = True
      if u == end: return math.exp(-dist[u])
      for v, w in g[u]:
        if seen[v] or dist[u] + w &gt; dist[v]: continue
        dist[v] = dist[u] + w        
        heapq.heappush(q, (dist[v], v))
    return 0</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1514-path-with-maximum-probability/">花花酱 LeetCode 1514. Path with Maximum Probability</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1514-path-with-maximum-probability/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1334-find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1334-find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 27 Jan 2020 06:58:54 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[floyd-warshall]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(n^3)]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6149</guid>

					<description><![CDATA[<p>There are&#160;n&#160;cities numbered from&#160;0&#160;to&#160;n-1. Given the array&#160;edges&#160;where&#160;edges[i] = [fromi, toi, weighti]&#160;represents a bidirectional and weighted edge between cities&#160;fromi&#160;and&#160;toi, and given the integer&#160;distanceThreshold. Return the city&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1334-find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/">花花酱 LeetCode 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1334. Find the City With the Smallest Number of Neighbors - 刷题找工作 EP303" width="500" height="375" src="https://www.youtube.com/embed/iE0tJ-8rPLQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>There are&nbsp;<code>n</code>&nbsp;cities numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n-1</code>. Given the array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>, weight<sub>i</sub>]</code>&nbsp;represents a bidirectional and weighted edge between cities&nbsp;<code>from<sub>i</sub></code>&nbsp;and&nbsp;<code>to<sub>i</sub></code>, and given the integer&nbsp;<code>distanceThreshold</code>.</p>



<p>Return the city with the smallest numberof&nbsp;cities that are reachable through some path and whose distance is&nbsp;<strong>at most</strong>&nbsp;<code>distanceThreshold</code>, If there are multiple such cities, return the city with the greatest number.</p>



<p>Notice that the distance of a path connecting cities&nbsp;<em><strong>i</strong></em>&nbsp;and&nbsp;<em><strong>j</strong></em>&nbsp;is equal to the sum of the edges&#8217; weights along that path.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/01/16/find_the_city_01.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
<strong>Output:</strong> 3
<strong>Explanation: </strong>The figure above describes the graph.&nbsp;
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -&gt; [City 1, City 2]&nbsp;
City 1 -&gt; [City 0, City 2, City 3]&nbsp;
City 2 -&gt; [City 0, City 1, City 3]&nbsp;
City 3 -&gt; [City 1, City 2]&nbsp;
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/01/16/find_the_city_02.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
<strong>Output:</strong> 0
<strong>Explanation: </strong>The figure above describes the graph.&nbsp;
The neighboring cities at a distanceThreshold = 2 for each city are:
City 0 -&gt; [City 1]&nbsp;
City 1 -&gt; [City 0, City 4]&nbsp;
City 2 -&gt; [City 3, City 4]&nbsp;
City 3 -&gt; [City 2, City 4]
City 4 -&gt; [City 1, City 2, City 3]&nbsp;
The city 0 has 1 neighboring city at a distanceThreshold = 2.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>2 &lt;= n &lt;= 100</code></li><li><code>1 &lt;= edges.length &lt;= n * (n - 1) / 2</code></li><li><code>edges[i].length == 3</code></li><li><code>0 &lt;= from<sub>i</sub>&nbsp;&lt; to<sub>i</sub>&nbsp;&lt; n</code></li><li><code>1 &lt;= weight<sub>i</sub>,&nbsp;distanceThreshold &lt;= 10^4</code></li><li>All pairs&nbsp;<code>(from<sub>i</sub>, to<sub>i</sub>)</code>&nbsp;are distinct.</li></ul>



<figure class="wp-block-image"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/01/1334-ep303-1.png" alt="" class="wp-image-6163" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/01/1334-ep303-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/01/1334-ep303-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/01/1334-ep303-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<h2><strong>Solution1: Floyd-Warshall</strong></h2>



<p>All pair shortest path</p>



<p>Time complexity: O(n^3)<br>Space complexity: O(n^2)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int findTheCity(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges, int distanceThreshold) {
    vector&lt;vector&lt;int&gt;&gt; dp(n, vector&lt;int&gt;(n, INT_MAX / 2));
    for (const auto&amp; e : edges)      
      dp[e[0]][e[1]] = dp[e[1]][e[0]] = e[2];    
    
    for (int k = 0; k &lt; n; ++k)
      for (int u = 0; u &lt; n; ++u)
        for (int v = 0; v &lt; n; ++v)
          dp[u][v] = min(dp[u][v], dp[u][k] + dp[k][v]);
    
    int ans = -1;
    int min_nb = INT_MAX;
    for (int u = 0; u &lt; n; ++u) {
      int nb = 0;
      for (int v = 0; v &lt; n; ++v)
        if (v != u &amp;&amp; dp[u][v] &lt;= distanceThreshold)
          ++nb;
      if (nb &lt;= min_nb) {
        min_nb = nb;
        ans = u;
      }
    }
    
    return ans;
  }
};</pre>
</div></div>



<p><strong>Solution 2: Dijkstra&#8217;s Algorithm</strong></p>



<p>Time complexity: O(V * ElogV) / worst O(n^3*logn), best O(n^2*logn)<br>Space complexity: O(V + E)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
// Author: Huahua
class Solution {
public:
  int findTheCity(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges, int t) {
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }
    
    // Returns the number of nodes within t from s.
    auto dijkstra = [&amp;](int s) {
      vector&lt;int&gt; dist(n, INT_MAX / 2);
      set&lt;pair&lt;int, int&gt;&gt; q; // &lt;dist, node&gt;
      vector&lt;set&lt;pair&lt;int, int&gt;&gt;::const_iterator&gt; its(n);
      dist[s] = 0;
      for (int i = 0; i &lt; n; ++i)
        its[i] = q.emplace(dist[i], i).first;
      while (!q.empty()) {
        auto it = cbegin(q);
        int d = it-&gt;first;
        int u = it-&gt;second;
        q.erase(it);        
        if (d &gt; t) break; // pruning
        for (const auto&amp; p : g[u]) {
          int v = p.first;
          int w = p.second;
          if (dist[v] &lt;= d + w) continue;
          // Decrease key
          q.erase(its[v]);
          its[v] = q.emplace(dist[v] = d + w, v).first;
        }
      }
      return count_if(begin(dist), end(dist), [t](int d) { return d &lt;= t; });
    };
    
    int ans = -1;
    int min_nb = INT_MAX;
    for (int i = 0; i &lt; n; ++i) {
      int nb = dijkstra(i);
      if (nb &lt;= min_nb) {
        min_nb = nb;
        ans = i;
      }
    }
    
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1334-find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/">花花酱 LeetCode 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1334-find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Dec 2019 04:19:11 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5966</guid>

					<description><![CDATA[<p>iven a&#160;m * n&#160;grid, where each cell is either&#160;0&#160;(empty)&#160;or&#160;1&#160;(obstacle).&#160;In one step, you can move up, down, left or right from and to an empty cell.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/">花花酱 LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>iven a&nbsp;<code>m * n</code>&nbsp;grid, where each cell is either&nbsp;<code>0</code>&nbsp;(empty)&nbsp;or&nbsp;<code>1</code>&nbsp;(obstacle).&nbsp;In one step, you can move up, down, left or right from and to an empty cell.</p>



<p>Return the minimum number of steps to walk from the upper left corner&nbsp;<code>(0, 0)</code>&nbsp;to the lower right corner&nbsp;<code>(m-1, n-1)</code>&nbsp;given that you can eliminate&nbsp;<strong>at most</strong>&nbsp;<code>k</code>&nbsp;obstacles. If it is not possible to find such&nbsp;walk return -1.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 
grid = 
[[0,0,0],
&nbsp;[1,1,0],
 [0,0,0],
&nbsp;[0,1,1],
 [0,0,0]], 
k = 1
<strong>Output:</strong> 6
<strong>Explanation: 
</strong>The shortest path without eliminating any obstacle is 10.&nbsp;
The shortest path with one obstacle elimination at position (3,2) is 6. Such path is <code>(0,0) -&gt; (0,1) -&gt; (0,2) -&gt; (1,2) -&gt; (2,2) -&gt; <strong>(3,2)</strong> -&gt; (4,2)</code>.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 
grid = 
[[0,1,1],
&nbsp;[1,1,1],
&nbsp;[1,0,0]], 
k = 1
<strong>Output:</strong> -1
<strong>Explanation: 
</strong>We need to eliminate at least two obstacles to find such a walk.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>grid.length&nbsp;== m</code></li><li><code>grid[0].length&nbsp;== n</code></li><li><code>1 &lt;= m, n &lt;= 40</code></li><li><code>1 &lt;= k &lt;= m*n</code></li><li><code>grid[i][j] == 0&nbsp;<strong>or</strong>&nbsp;1</code></li><li><code>grid[0][0] == grid[m-1][n-1] == 0</code></li></ul>



<h2><strong>Solution: BFS</strong></h2>



<p>State: (x, y, k) where k is the number of obstacles along the path.</p>



<p>Time complexity: O(m*n*k)<br>Space complexity: O(m*n*k)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua, 8 ms, 10.5 MB
class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int k) {
    const vector&lt;int&gt; dirs{0, 1, 0, -1, 0};
    const int n = grid.size();
    const int m = grid[0].size();
    vector&lt;vector&lt;int&gt;&gt; seen(n, vector&lt;int&gt;(m, INT_MAX));
    queue&lt;tuple&lt;int, int, int&gt;&gt; q; 
    int steps = 0;
    q.emplace(0, 0, 0);
    seen[0][0] = 0;
    while (!q.empty()) {
      int size = q.size();
      while (size--) {
        int cx, cy, co;
        tie(cx, cy, co) = q.front(); q.pop();         
        if (cx == m - 1 &amp;&amp; cy == n - 1) return steps;
        for (int i = 0; i &lt; 4; ++i) {
          int x = cx + dirs[i];
          int y = cy + dirs[i + 1];
          if (x &lt; 0 || y &lt; 0 || x &gt;= m || y &gt;= n) continue;
          int o = co + grid[y][x];
          if (o &gt;= seen[y][x] || o &gt; k) continue;            
          seen[y][x] = o;
          q.emplace(x, y, o);
        }
      }
      ++steps;
    }
    return -1;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: DP</strong></h2>



<p>Time complexity: O(mnk)<br>Space complexity: O(mnk)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">Bottom-Up</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// AC 236 ms
class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int k) {
    constexpr int kInf = 1e9;
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp(m + 2, vector&lt;vector&lt;int&gt;&gt;(n + 2, vector&lt;int&gt;(k + 1, kInf)));
    dp[1][1][0] = 0;
    for (int s = 0; s &lt; 3; ++s)
      for (int i = 1; i &lt;= m; ++i)
        for (int j = 1; j &lt;= n; ++j) {
          const int o = grid[i - 1][j - 1];
          for (int z = 0; z + o &lt;= k; ++z)
            dp[i][j][z + o] = min(dp[i][j][z + o],
                                  min({dp[i - 1][j][z],
                                       dp[i][j - 1][z],
                                       dp[i + 1][j][z],
                                       dp[i][j + 1][z]}) + 1);
        }
    int ans = *min_element(begin(dp[m][n]), end(dp[m][n]));
    return ans &gt;= kInf ? -1 : ans;
  }
};</pre>

</div><h2 class="tabtitle">Top-Down</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int K) {
    constexpr int kInf = 1e9;
    const vector&lt;int&gt; dirs{0, 1, 0, -1, 0};
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; mem(m + 2, vector&lt;vector&lt;int&gt;&gt;(n + 2, vector&lt;int&gt;(K + 1, -1)));
    vector&lt;vector&lt;int&gt;&gt; seen(m + 2, vector&lt;int&gt;(n + 2));    
    function&lt;int(int, int, int)&gt; dp = [&amp;](int x, int y, int k) {      
      if (x &lt; 1 || x &gt; n || y &lt; 1 || y &gt; m || k &lt; 0 || seen[y][x]) return kInf;
      if (x == 1 &amp;&amp; y == 1) return 0;
      if (mem[y][x][k] != -1) return mem[y][x][k];
      seen[y][x] = 1;
      int ans = kInf;
      for (int i = 0; i &lt; 4; ++i)
        ans = min(ans, 1 + dp(x + dirs[i], y + dirs[i + 1], k - grid[y - 1][x - 1]));
      seen[y][x] = 0;      
      return mem[y][x][k] = ans;
    };        
    const int ans = dp(n, m, K);
    return ans &gt;= kInf ? -1 : ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/">花花酱 LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1138. Alphabet Board Path</title>
		<link>https://zxi.mytechroad.com/blog/geometry/leetcode-1138-alphabet-board-path/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/leetcode-1138-alphabet-board-path/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Jul 2019 04:20:52 +0000</pubDate>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5357</guid>

					<description><![CDATA[<p>On an alphabet board, we start at position&#160;(0, 0), corresponding to character&#160;board[0][0]. Here,&#160;board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]. We may make the following&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-1138-alphabet-board-path/">花花酱 LeetCode 1138. Alphabet Board Path</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>On an alphabet board, we start at position&nbsp;<code>(0, 0)</code>, corresponding to character&nbsp;<code>board[0][0]</code>.</p>



<p>Here,&nbsp;<code>board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]</code>.</p>



<p>We may make the following moves:</p>



<ul><li><code>'U'</code>&nbsp;moves our position up one row, if the square exists;</li><li><code>'D'</code>&nbsp;moves our position down one row, if the square exists;</li><li><code>'L'</code>&nbsp;moves our position left one column, if the square exists;</li><li><code>'R'</code>&nbsp;moves our position right one column, if the square exists;</li><li><code>'!'</code>&nbsp;adds the character&nbsp;<code>board[r][c]</code>&nbsp;at our current position&nbsp;<code>(r, c)</code>&nbsp;to the&nbsp;answer.</li></ul>



<p>Return a sequence of moves that makes our answer equal to&nbsp;<code>target</code>&nbsp;in the minimum number of moves.&nbsp; You may return any path that does so.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> target = "leet"
<strong>Output:</strong> "DDR!UURRR!!DDD!"
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> target = "code"
<strong>Output:</strong> "RR!DDRR!UUL!R!"
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= target.length &lt;= 100</code></li><li><code>target</code>&nbsp;consists only of English lowercase letters.</li></ul>



<h2><strong>Solution: Manhattan walk</strong></h2>



<p>Compute the coordinates of each char, walk from (x1, y1) to (x2, y2) in Manhattan way. <br><strong>Be aware of the last row, we can only walk on &#8216;z&#8217;, so go left and up first if needed.</strong></p>



<p>Time complexity: O(26*26 + n)<br>Space complexity: O(26*26)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  string alphabetBoardPath(string target) {    
    vector&lt;vector&lt;string&gt;&gt; paths(26, vector&lt;string&gt;(26));
    for (int s = 0; s &lt; 26; ++s)
      for (int t = 0; t &lt; 26; ++t) {
        int dx = t % 5 - s % 5;
        int dy = t / 5 - s / 5; 
        string path;
        while (dx &lt; 0) { path.push_back('L'); dx++; }
        while (dy &lt; 0) { path.push_back('U'); dy++; }
        while (dx &gt; 0) { path.push_back('R'); dx--; }
        while (dy &gt; 0) { path.push_back('D'); dy--; }
        paths[s][t] = path;
      }
    
    char l = 'a';
    string ans;
    for (char c : target) {
      ans += paths[l - 'a'][c - 'a'] + &quot;!&quot;;
      l = c;
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-1138-alphabet-board-path/">花花酱 LeetCode 1138. Alphabet Board Path</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/geometry/leetcode-1138-alphabet-board-path/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 934. Shortest Bridge</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-934-shortest-bridge/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-934-shortest-bridge/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 04 Nov 2018 08:00:23 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4251</guid>

					<description><![CDATA[<p>Problem https://leetcode.com/problems/shortest-bridge/description/ In a given 2D binary array A, there are two islands.  (An island is a 4-directionally connected group of 1s not connected to any other&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-934-shortest-bridge/">花花酱 LeetCode 934. Shortest Bridge</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/JU-g1mNUaSE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p><a href="https://leetcode.com/problems/shortest-bridge/description/">https://leetcode.com/problems/shortest-bridge/description/</a></p>
<p>In a given 2D binary array <code>A</code>, there are two islands.  (An island is a 4-directionally connected group of <code>1</code>s not connected to any other 1s.)</p>
<p>Now, we may change <code>0</code>s to <code>1</code>s so as to connect the two islands together to form 1 island.</p>
<p>Return the smallest number of <code>0</code>s that must be flipped.  (It is guaranteed that the answer is at least 1.)</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-1-1">[[0,1],[1,0]]</span>
<strong>Output: </strong>1
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-2-1">[[0,1,0],[0,0,0],[0,0,1]]</span>
<strong>Output: </strong>2
</pre>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-3-1">[[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]</span>
<strong>Output: </strong><span id="example-output-3">1</span></pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length = A[0].length &lt;= 100</code></li>
<li><code>A[i][j] == 0</code> or <code>A[i][j] == 1</code></li>
</ol>
<p><img class="alignnone size-full wp-image-4329" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/934-ep234.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/934-ep234.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/934-ep234-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/934-ep234-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Solution: DFS + BFS</strong></h1>
<ol>
<li>Use DFS to find one island and color all the nodes as 2 (BLUE).</li>
<li>Use BFS to find the shortest path from any nodes with color 2 (BLUE) to any nodes with color 1 (RED).</li>
</ol>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">class Solution {
public:
  int shortestBridge(vector&lt;vector&lt;int&gt;&gt;&amp; A) {
    queue&lt;pair&lt;int, int&gt;&gt; q;
    bool found = false;
    for (int i = 0; i &lt; A.size() &amp;&amp; !found; ++i)
      for (int j = 0; j &lt; A[0].size() &amp;&amp; !found; ++j)
        if (A[i][j]) {
          dfs(A, j, i, q);
          found = true;
        }
    
    int steps = 0;
    vector&lt;int&gt; dirs{0, 1, 0, -1, 0};
    while (!q.empty()) {      
      size_t size = q.size();
      while (size--) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int i = 0; i &lt; 4; ++i) {
          int tx = x + dirs[i];
          int ty = y + dirs[i + 1];
          if (tx &lt; 0 || ty &lt; 0 || tx &gt;= A[0].size() || ty &gt;= A.size() || A[ty][tx] == 2) continue;          
          if (A[ty][tx] == 1) return steps;
          A[ty][tx] = 2;
          q.emplace(tx, ty);
        }
      }
      ++steps;
    }
    return -1;
  }
private:  
  void dfs(vector&lt;vector&lt;int&gt;&gt;&amp; A, int x, int y, queue&lt;pair&lt;int, int&gt;&gt;&amp; q) {
    if (x &lt; 0 || y &lt; 0 || x &gt;= A[0].size() || y &gt;= A.size() || A[y][x] != 1) return;
    A[y][x] = 2;
    q.emplace(x, y);
    dfs(A, x - 1, y, q);
    dfs(A, x, y - 1, q);
    dfs(A, x + 1, y, q);
    dfs(A, x, y + 1, q);
  }
};</pre><p></div></div></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-827-making-a-large-island/">花花酱 LeetCode 827. Making A Large Island</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-695-max-area-of-island/">花花酱 LeetCode 695. Max Area of Island</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/">花花酱 LeetCode 882. Reachable Nodes In Subdivided Graph</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-743-network-delay-time/">花花酱 LeetCode 743. Network Delay Time</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-934-shortest-bridge/">花花酱 LeetCode 934. Shortest Bridge</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-934-shortest-bridge/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 882. Reachable Nodes In Subdivided Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Aug 2018 03:49:13 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3439</guid>

					<description><![CDATA[<p>Problem Starting with an undirected graph (the &#8220;original graph&#8221;) with nodes from 0 to N-1, subdivisions are made to some of the edges. The graph is given as follows: edges[k] is a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/">花花酱 LeetCode 882. Reachable Nodes In Subdivided Graph</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/SGki2XeWBEo?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Starting with an <strong>undirected</strong> graph (the &#8220;original graph&#8221;) with nodes from <code>0</code> to <code>N-1</code>, subdivisions are made to some of the edges.</p>
<p>The graph is given as follows: <code>edges[k]</code> is a list of integer pairs <code>(i, j, n)</code> such that <code>(i, j)</code> is an edge of the original graph,</p>
<p>and <code>n</code> is the total number of <strong>new</strong> nodes on that edge.</p>
<p>Then, the edge <code>(i, j)</code> is deleted from the original graph, <code>n</code> new nodes <code>(x_1, x_2, ..., x_n)</code> are added to the original graph,</p>
<p>and <code>n+1</code> new edges <code>(i, x_1), (x_1, x_2), (x_2, x_3), ..., (x_{n-1}, x_n), (x_n, j)</code> are added to the original graph.</p>
<p>Now, you start at node <code>0</code> from the original graph, and in each move, you travel along one edge.</p>
<p>Return how many nodes you can reach in at most <code>M</code> moves.</p>
<p>&nbsp;</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false "><strong>Input: </strong>edge = <span id="example-input-1-1">[[0,1,10],[0,2,1],[1,2,2]]</span>, M = <span id="example-input-1-2">6</span>, N = <span id="example-input-1-3">3</span> 
<strong>Output: </strong><span id="example-output-1">13</span> 
<strong>Explanation: </strong> The nodes that are reachable in the final graph after M = 6 moves are indicated below. <img src="https://s3-lc-upload.s3.amazonaws.com/uploads/2018/08/01/origfinal.png" alt="" /></pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], M = 10, N = 4 
<strong>Output: </strong>23</pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>0 &lt;= edges.length &lt;= 10000</code></li>
<li><code>0 &lt;= edges[i][0] &lt; edges[i][1] &lt; N</code></li>
<li>There does not exist any <code>i != j</code> for which <code>edges[i][0] == edges[j][0]</code> and <code>edges[i][1] == edges[j][1]</code>.</li>
<li>The original graph has no parallel edges.</li>
<li><code>0 &lt;= edges[i][2] &lt;= 10000</code></li>
<li><code>0 &lt;= M &lt;= 10^9</code></li>
<li><code><span style="font-family: monospace;">1 &lt;= N &lt;= 3000</span></code></li>
</ol>
<h1><strong>Solution: Dijkstra Shortest Path</strong></h1>
<p><img class="alignnone size-full wp-image-3468" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-3467" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-3472" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-3.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/866-ep215-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p>Compute the shortest from 0 to rest of the nodes. Use HP to mark the maximum moves left to reach each node.</p>
<p>HP[u] = a, HP[v] = b, new_nodes[u][v] = c</p>
<p>nodes covered between a&lt;-&gt;b = min(c, a + b)</p>
<p>Time complexity: O(ElogE)</p>
<p>Space complexity: O(E)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 88 ms
class Solution {
public:
  int reachableNodes(vector&lt;vector&lt;int&gt;&gt;&amp; edges, int M, int N) {
    unordered_map&lt;int, unordered_map&lt;int, int&gt;&gt; g;
    for (const auto&amp; e : edges)
      g[e[0]][e[1]] = g[e[1]][e[0]] = e[2];
    
    priority_queue&lt;pair&lt;int, int&gt;&gt; q;   // {hp, node}, sort by HP desc
    unordered_map&lt;int, int&gt; HP;         // node -&gt; max HP left
    q.push({M, 0});
    while (!q.empty()) {
      int hp = q.top().first;
      int cur = q.top().second;
      q.pop();
      if (HP.count(cur)) continue;
      HP[cur] = hp;
      for (const auto&amp; pair : g[cur]) {
        int nxt = pair.first;
        int nxt_hp = hp - pair.second - 1;
        if (HP.count(nxt) || nxt_hp &lt; 0) continue;
        q.push({nxt_hp, nxt});
      }
    }
    
    int ans = HP.size(); // Original nodes covered.
    for (const auto&amp; e : edges) {
      int uv = HP.count(e[0]) ? HP[e[0]] : 0;
      int vu = HP.count(e[1]) ? HP[e[1]] : 0;
      ans += min(e[2], uv + vu);
    }
    return ans;
  }
};</pre><p>Optimized Dijkstra (replace hashmap with vector)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 56 ms (beats 88%)
class Solution {
public:
  int reachableNodes(vector&lt;vector&lt;int&gt;&gt;&amp; edges, int M, int N) {
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(N);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }
    
    set&lt;pair&lt;int, int&gt;&gt; q;           // {hp, node}, sort by HP asc
    vector&lt;int&gt; HP(N, INT_MIN);      // node -&gt; HP left
    q.insert({M, 0});
    int ans = 0;
    while (!q.empty()) {
      auto last_it = prev(end(q));
      int hp = last_it-&gt;first;
      int cur = last_it-&gt;second;
      q.erase(last_it);
      if (HP[cur] != INT_MIN) continue;
      HP[cur] = hp;
      ++ans;
      for (const auto&amp; pair : g[cur]) {
        int nxt = pair.first;
        int nxt_hp = hp - pair.second - 1;
        if (nxt_hp &lt; 0 || HP[nxt] != INT_MIN) continue;
        q.insert({nxt_hp, nxt});
      }
    }
        
    for (const auto&amp; e : edges) {
      const int uv = HP[e[0]] == INT_MIN ?  0 : HP[e[0]];
      const int vu = HP[e[1]] == INT_MIN ?  0 : HP[e[1]];
      ans += min(e[2], uv + vu);
    }
    return ans;
  }
};</pre><p>Using SPFA</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 56 ms (beats 88%)
class Solution {
public:
  int reachableNodes(vector&lt;vector&lt;int&gt;&gt;&amp; edges, int M, int N) {
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(N);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }
    
    queue&lt;int&gt; q;               
    vector&lt;int&gt; HP(N, INT_MIN);
    vector&lt;bool&gt; in_q(N);
    HP[0] = M;
    q.push(0);
    in_q[0] = true;
    
    // SPFA (Shortest Path Faster Algorithm).
    while (!q.empty()) {      
      int u = q.front(); q.pop();
      in_q[u] = false;
      for (const auto&amp; pair : g[u]) {
        int v = pair.first;
        int new_hp = HP[u] - pair.second - 1;        
        if (new_hp &lt; 0 || new_hp &lt;= HP[v]) continue;
        HP[v] = new_hp;
        if (in_q[v]) continue;
        q.push(v);
        in_q[v] = true;
      }
    }
    
    int ans = 0;
    for (int i = 0; i &lt; N; ++i) ans += HP[i] &gt;= 0;
    for (const auto&amp; e : edges) {
      const int uv = HP[e[0]] == INT_MIN ?  0 : HP[e[0]];
      const int vu = HP[e[1]] == INT_MIN ?  0 : HP[e[1]];
      ans += min(e[2], uv + vu);
    }
    return ans;
  }
};</pre><p>&nbsp;</p>
<p>BFS</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 108 ms
class Solution {
public:
  int reachableNodes(vector&lt;vector&lt;int&gt;&gt;&amp; edges, int M, int N) {
    unordered_map&lt;int, unordered_map&lt;int, int&gt;&gt; g;
    for (const auto&amp; e : edges)
      g[e[0]][e[1]] = g[e[1]][e[0]] = e[2];
    
    queue&lt;pair&lt;int, int&gt;&gt; q;            // {hp, node}
    unordered_map&lt;int, int&gt; HP;         // node -&gt; max HP left
    q.push({M, 0});
    while (!q.empty()) {
      int hp = q.front().first;
      int cur = q.front().second;
      q.pop();
      if (HP.count(cur) &amp;&amp; HP[cur] &gt; hp) continue;
      HP[cur] = hp;
      for (const auto&amp; pair : g[cur]) {
        int nxt = pair.first;
        int nxt_hp = hp - pair.second - 1;
        if (nxt_hp &lt; 0 || (HP.count(nxt) &amp;&amp; HP[nxt] &gt; nxt_hp)) continue;
        q.push({nxt_hp, nxt});
      }
    }
    
    int ans = HP.size(); // Original nodes covered.
    for (const auto&amp; e : edges) {
      int uv = HP.count(e[0]) ? HP[e[0]] : 0;
      int vu = HP.count(e[1]) ? HP[e[1]] : 0;
      ans += min(e[2], uv + vu);
    }
    return ans;
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/">花花酱 LeetCode 882. Reachable Nodes In Subdivided Graph</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-882-reachable-nodes-in-subdivided-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
