<?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>Graph Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/category/graph/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/category/graph/</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>Graph Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/category/graph/</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 2658. Maximum Number of Fish in a Grid</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Apr 2023 15:30:49 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[connected components]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10032</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;2D matrix&#160;grid&#160;of size&#160;m x n, where&#160;(r, c)&#160;represents: A&#160;land&#160;cell if&#160;grid[r][c] = 0, or A&#160;water&#160;cell containing&#160;grid[r][c]&#160;fish, if&#160;grid[r][c] &#62; 0. A fisher can start at&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/">花花酱 LeetCode 2658. Maximum Number of Fish in a Grid</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 matrix&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>m x n</code>, where&nbsp;<code>(r, c)</code>&nbsp;represents:</p>



<ul><li>A&nbsp;<strong>land</strong>&nbsp;cell if&nbsp;<code>grid[r][c] = 0</code>, or</li><li>A&nbsp;<strong>water</strong>&nbsp;cell containing&nbsp;<code>grid[r][c]</code>&nbsp;fish, if&nbsp;<code>grid[r][c] &gt; 0</code>.</li></ul>



<p>A fisher can start at any&nbsp;<strong>water</strong>&nbsp;cell&nbsp;<code>(r, c)</code>&nbsp;and can do the following operations any number of times:</p>



<ul><li>Catch all the fish at cell&nbsp;<code>(r, c)</code>, or</li><li>Move to any adjacent&nbsp;<strong>water</strong>&nbsp;cell.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;number of fish the fisher can catch if he chooses his starting cell optimally, or&nbsp;</em><code>0</code>&nbsp;if no water cell exists.</p>



<p>An&nbsp;<strong>adjacent</strong>&nbsp;cell of the cell&nbsp;<code>(r, c)</code>, is one of the cells&nbsp;<code>(r, c + 1)</code>,&nbsp;<code>(r, c - 1)</code>,&nbsp;<code>(r + 1, c)</code>&nbsp;or&nbsp;<code>(r - 1, c)</code>&nbsp;if it exists.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/03/29/example.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[0,2,1,0],[4,0,0,3],[1,0,0,4],[0,3,2,0]]
<strong>Output:</strong> 7
<strong>Explanation:</strong> The fisher can start at cell <code>(1,3)</code> and collect 3 fish, then move to cell <code>(2,3)</code>&nbsp;and collect 4 fish.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/03/29/example2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> The fisher can start at cells (0,0) or (3,3) and collect a single fish. 
</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</code></li><li><code>0 &lt;= grid[i][j] &lt;= 10</code></li></ul>



<h2><strong>Solution: Connected Component</strong></h2>



<p>Similar to <a href="https://zxi.mytechroad.com/blog/graph/leetcode-695-max-area-of-island/">花花酱 LeetCode 695. Max Area of Island</a></p>



<p>Find the connected component that has the max sum.</p>



<p>Time complexity: O(mn)<br>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:
  int findMaxFish(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    function&lt;int(int, int)&gt; dfs = [&amp;](int r, int c) {
      if (r &lt; 0 || r &gt;= m || c &lt; 0 || c &gt;= n || !grid[r][c]) return 0;      
      return exchange(grid[r][c], 0) 
        + dfs(r - 1, c) + dfs(r, c - 1) + dfs(r + 1, c) + dfs(r, c + 1);
    };
    int ans = 0;
    for (int r = 0; r &lt; m; ++r)
      for (int c = 0; c &lt; n; ++c)
        ans = max(ans, dfs(r, c));
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/">花花酱 LeetCode 2658. Maximum Number of Fish in a Grid</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-2658-maximum-number-of-fish-in-a-grid/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 1061. Lexicographically Smallest Equivalent String</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 14 Jan 2023 20:24:29 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9916</guid>

					<description><![CDATA[<p>You are given two strings of the same length&#160;s1&#160;and&#160;s2&#160;and a string&#160;baseStr. We say&#160;s1[i]&#160;and&#160;s2[i]&#160;are equivalent characters. For example, if&#160;s1 = "abc"&#160;and&#160;s2 = "cde", then we have&#160;'a'&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/">花花酱 LeetCode 1061. Lexicographically Smallest Equivalent String</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 strings of the same length&nbsp;<code>s1</code>&nbsp;and&nbsp;<code>s2</code>&nbsp;and a string&nbsp;<code>baseStr</code>.</p>



<p>We say&nbsp;<code>s1[i]</code>&nbsp;and&nbsp;<code>s2[i]</code>&nbsp;are equivalent characters.</p>



<ul><li>For example, if&nbsp;<code>s1 = "abc"</code>&nbsp;and&nbsp;<code>s2 = "cde"</code>, then we have&nbsp;<code>'a' == 'c'</code>,&nbsp;<code>'b' == 'd'</code>, and&nbsp;<code>'c' == 'e'</code>.</li></ul>



<p>Equivalent characters follow the usual rules of any equivalence relation:</p>



<ul><li><strong>Reflexivity:</strong>&nbsp;<code>'a' == 'a'</code>.</li><li><strong>Symmetry:</strong>&nbsp;<code>'a' == 'b'</code>&nbsp;implies&nbsp;<code>'b' == 'a'</code>.</li><li><strong>Transitivity:</strong>&nbsp;<code>'a' == 'b'</code>&nbsp;and&nbsp;<code>'b' == 'c'</code>&nbsp;implies&nbsp;<code>'a' == 'c'</code>.</li></ul>



<p>For example, given the equivalency information from&nbsp;<code>s1 = "abc"</code>&nbsp;and&nbsp;<code>s2 = "cde"</code>,&nbsp;<code>"acd"</code>&nbsp;and&nbsp;<code>"aab"</code>&nbsp;are equivalent strings of&nbsp;<code>baseStr = "eed"</code>, and&nbsp;<code>"aab"</code>&nbsp;is the lexicographically smallest equivalent string of&nbsp;<code>baseStr</code>.</p>



<p>Return&nbsp;<em>the lexicographically smallest equivalent string of&nbsp;</em><code>baseStr</code><em>&nbsp;by using the equivalency information from&nbsp;</em><code>s1</code><em>&nbsp;and&nbsp;</em><code>s2</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s1 = "parker", s2 = "morris", baseStr = "parser"
<strong>Output:</strong> "makkek"
<strong>Explanation:</strong> Based on the equivalency information in s1 and s2, we can group their characters as [m,p], [a,o], [k,r,s], [e,i].
The characters in each group are equivalent and sorted in lexicographical order.
So the answer is "makkek".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s1 = "hello", s2 = "world", baseStr = "hold"
<strong>Output:</strong> "hdld"
<strong>Explanation: </strong>Based on the equivalency information in s1 and s2, we can group their characters as [h,w], [d,e,o], [l,r].
So only the second letter 'o' in baseStr is changed to 'd', the answer is "hdld".
</pre>



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



<pre class="crayon-plain-tag">&lt;strong&gt;Input:&lt;/strong&gt; s1 = &quot;leetcode&quot;, s2 = &quot;programs&quot;, baseStr = &quot;sourcecode&quot;
&lt;strong&gt;Output:&lt;/strong&gt; &quot;aauaaaaada&quot;
&lt;strong&gt;Explanation:&lt;/strong&gt; We group the equivalent characters in s1 and s2 as [a,o,e,r,s,c], [l,p], [g,t] and [d,m], thus all letters in baseStr except 'u' and 'd' are transformed to 'a', the answer is &quot;aauaaaaada&quot;.</pre>



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



<ul><li><code>1 &lt;= s1.length, s2.length, baseStr &lt;= 1000</code></li><li><code>s1.length == s2.length</code></li><li><code>s1</code>,&nbsp;<code>s2</code>, and&nbsp;<code>baseStr</code>&nbsp;consist of lowercase English letters.</li></ul>



<h2><strong>Solution: Union Find</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png" alt="" class="wp-image-9918" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Time complexity: O(n + m)<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:
  string smallestEquivalentString(string s1, string s2, string baseStr) {
    vector&lt;int&gt; p(26);
    iota(begin(p), end(p), 0);
    function&lt;int(int)&gt; find = [&amp;](int x) {
      return p[x] == x ? x : p[x] = find(p[x]);
    };
    for (int i = 0; i &lt; s1.length(); ++i) {
      int r1 = find(s1[i] - 'a');
      int r2 = find(s2[i] - 'a');
      if (r2 &lt; r1) swap(r1, r2);
      p[r2] = r1;
    }
    
    string ans(baseStr);
    for (int i = 0; i &lt; baseStr.length(); ++i) {
      ans[i] = find(baseStr[i] - 'a') + 'a';
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/">花花酱 LeetCode 1061. Lexicographically Smallest Equivalent String</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-1061-lexicographically-smallest-equivalent-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 26 Nov 2022 16:41:02 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9905</guid>

					<description><![CDATA[<p>There is a tree (i.e., a connected, undirected graph with no cycles) structure country network consisting of&#160;n&#160;cities numbered from&#160;0&#160;to&#160;n - 1&#160;and exactly&#160;n - 1&#160;roads. The&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/">花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</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 tree (i.e., a connected, undirected graph with no cycles) structure country network consisting of&nbsp;<code>n</code>&nbsp;cities numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;and exactly&nbsp;<code>n - 1</code>&nbsp;roads. The capital city is city&nbsp;<code>0</code>. You are given a 2D integer array&nbsp;<code>roads</code>&nbsp;where&nbsp;<code>roads[i] = [a<sub>i</sub>, b<sub>i</sub>]</code>&nbsp;denotes that there exists a&nbsp;<strong>bidirectional road</strong>&nbsp;connecting cities&nbsp;<code>a<sub>i</sub></code>&nbsp;and&nbsp;<code>b<sub>i</sub></code>.</p>



<p>There is a meeting for the representatives of each city. The meeting is in the capital city.</p>



<p>There is a car in each city. You are given an integer&nbsp;<code>seats</code>&nbsp;that indicates the number of seats in each car.</p>



<p>A representative can use the car in their city to travel or change the car and ride with another representative. The cost of traveling between two cities is one liter of fuel.</p>



<p>Return&nbsp;<em>the minimum number of liters of fuel to reach the capital city</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/09/22/a4c380025e3ff0c379525e96a7d63a3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [[0,1],[0,2],[0,3]], seats = 5
<strong>Output:</strong> 3
<strong>Explanation:</strong> 
- Representative<sub>1</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>2</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>3</sub> goes directly to the capital with 1 liter of fuel.
It costs 3 liters of fuel at minimum. 
It can be proven that 3 is the minimum number of liters of fuel needed.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [[3,1],[3,2],[1,0],[0,4],[0,5],[4,6]], seats = 2
<strong>Output:</strong> 7
<strong>Explanation:</strong> 
- Representative<sub>2</sub> goes directly to city 3 with 1 liter of fuel.
- Representative<sub>2</sub> and representative<sub>3</sub> go together to city 1 with 1 liter of fuel.
- Representative<sub>2</sub> and representative<sub>3</sub> go together to the capital with 1 liter of fuel.
- Representative<sub>1</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>5</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>6</sub> goes directly to city 4 with 1 liter of fuel.
- Representative<sub>4</sub> and representative<sub>6</sub> go together to the capital with 1 liter of fuel.
It costs 7 liters of fuel at minimum. 
It can be proven that 7 is the minimum number of liters of fuel needed.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/09/27/efcf7f7be6830b8763639cfd01b690a.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [], seats = 1
<strong>Output:</strong> 0
<strong>Explanation:</strong> No representatives need to travel to the capital city.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>roads.length == n - 1</code></li><li><code>roads[i].length == 2</code></li><li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub>&nbsp;&lt; n</code></li><li><code>a<sub>i</sub>&nbsp;!= b<sub>i</sub></code></li><li><code>roads</code>&nbsp;represents a valid tree.</li><li><code>1 &lt;= seats &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Greedy + DFS</strong></h2>



<p>To reach the minimum cost, we must share cars if possible, say X reps from children nodes to an intermediate node u on the way towards capital 0.  Then they all changes cars at node u, and we need (X + 1) // seats cars/fuel from u to 0.</p>



<p>We use DFS to count # of reps at each node u while accumulating the total cost.</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:
  long long minimumFuelCost(vector&lt;vector&lt;int&gt;&gt;&amp; roads, int seats) {
    long long ans = 0;
    vector&lt;vector&lt;int&gt;&gt; g(roads.size() + 1);
    for (const vector&lt;int&gt;&amp; r : roads) {
      g[r[0]].push_back(r[1]);
      g[r[1]].push_back(r[0]);
    }
    // Returns total # of children of u.
    function&lt;int(int, int)&gt; dfs = [&amp;](int u, int p, int rep = 1) {      
      for (int v : g[u])
        if (v != p) rep += dfs(v, u);
      if (u) ans += (rep + seats - 1) / seats;
      return rep;
    };
    dfs(0, -1);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/">花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</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-2477-minimum-fuel-cost-to-report-to-the-capital/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2374. Node With Highest Edge Score</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 15 Aug 2022 04:36:05 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9787</guid>

					<description><![CDATA[<p>You are given a directed graph with&#160;n&#160;nodes labeled from&#160;0&#160;to&#160;n - 1, where each node has&#160;exactly one&#160;outgoing edge. The graph is represented by a given&#160;0-indexed&#160;integer array&#160;edges&#160;of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/">花花酱 LeetCode 2374. Node With Highest Edge Score</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 directed graph with&nbsp;<code>n</code>&nbsp;nodes labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>, where each node has&nbsp;<strong>exactly one</strong>&nbsp;outgoing edge.</p>



<p>The graph is represented by a given&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>edges</code>&nbsp;of length&nbsp;<code>n</code>, where&nbsp;<code>edges[i]</code>&nbsp;indicates that there is a&nbsp;<strong>directed</strong>&nbsp;edge from node&nbsp;<code>i</code>&nbsp;to node&nbsp;<code>edges[i]</code>.</p>



<p>The&nbsp;<strong>edge score</strong>&nbsp;of a node&nbsp;<code>i</code>&nbsp;is defined as the sum of the&nbsp;<strong>labels</strong>&nbsp;of all the nodes that have an edge pointing to&nbsp;<code>i</code>.</p>



<p>Return&nbsp;<em>the node with the highest&nbsp;<strong>edge score</strong></em>. If multiple nodes have the same&nbsp;<strong>edge score</strong>, return the node with the&nbsp;<strong>smallest</strong>&nbsp;index.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/06/20/image-20220620195403-1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [1,0,0,0,0,7,7,5]
<strong>Output:</strong> 7
<strong>Explanation:</strong>
- The nodes 1, 2, 3 and 4 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 + 3 + 4 = 10.
- The node 0 has an edge pointing to node 1. The edge score of node 1 is 0.
- The node 7 has an edge pointing to node 5. The edge score of node 5 is 7.
- The nodes 5 and 6 have an edge pointing to node 7. The edge score of node 7 is 5 + 6 = 11.
Node 7 has the highest edge score so return 7.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/06/20/image-20220620200212-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [2,0,0,2]
<strong>Output:</strong> 0
<strong>Explanation:</strong>
- The nodes 1 and 2 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 = 3.
- The nodes 0 and 3 have an edge pointing to node 2. The edge score of node 2 is 0 + 3 = 3.
Nodes 0 and 2 both have an edge score of 3. Since node 0 has a smaller index, we return 0.
</pre>



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



<ul><li><code>n == edges.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= edges[i] &lt; n</code></li><li><code>edges[i] != i</code></li></ul>



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



<p>Use an array to store the score of each node.</p>



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



<p>use <a href="https://en.cppreference.com/w/cpp/algorithm/max_element">max_element</a> to find the largest element.</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int edgeScore(vector&lt;int&gt;&amp; edges) {
    const int n = edges.size();
    vector&lt;long&gt; s(n);
    for (int i = 0; i &lt; n; ++i)
      s[edges[i]] += i;
    return max_element(begin(s), end(s)) - begin(s);
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/">花花酱 LeetCode 2374. Node With Highest Edge Score</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-2374-node-with-highest-edge-score/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 133. Clone Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 14 Aug 2022 16:33:26 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[clone]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9775</guid>

					<description><![CDATA[<p>Given a reference of a node in a connected undirected graph. Return a&#160;deep copy&#160;(clone) of the graph. Each node in the graph contains a value (int) and&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/">花花酱 LeetCode 133. Clone 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[
<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 133. Clone Graph - 刷题找工作 EP400" width="500" height="281" src="https://www.youtube.com/embed/NCQMg-WMRZc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a reference of a node in a <strong><a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/Connectivity_(graph_theory)#Connected_graph" target="_blank">connected</a></strong> undirected graph.</p>



<p>Return a&nbsp;<a href="https://en.wikipedia.org/wiki/Object_copying#Deep_copy" target="_blank" rel="noreferrer noopener"><strong>deep copy</strong></a>&nbsp;(clone) of the graph.</p>



<p>Each node in the graph contains a value (<code>int</code>) and a list (<code>List[Node]</code>) of its neighbors.</p>



<pre class="wp-block-preformatted;crayon:false">class Node {
    public int val;
    public List<Node> neighbors;
}
</pre>



<p><strong>Test case format:</strong></p>



<p>For simplicity, each node&#8217;s value is the same as the node&#8217;s index (1-indexed). For example, the first node with&nbsp;<code>val == 1</code>, the second node with&nbsp;<code>val == 2</code>, and so on. The graph is represented in the test case using an adjacency list.</p>



<p><strong>An adjacency list</strong>&nbsp;is a collection of unordered&nbsp;<strong>lists</strong>&nbsp;used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.</p>



<p>The given node will always be the first node with&nbsp;<code>val = 1</code>. You must return the&nbsp;<strong>copy of the given node</strong>&nbsp;as a reference to the cloned graph.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = [[2,4],[1,3],[2,4],[1,3]]
<strong>Output:</strong> [[2,4],[1,3],[2,4],[1,3]]
<strong>Explanation:</strong> There are 4 nodes in the graph.
1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = [[]]
<strong>Output:</strong> [[]]
<strong>Explanation:</strong> Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = []
<strong>Output:</strong> []
<strong>Explanation:</strong> This an empty graph, it does not have any nodes.
</pre>



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



<ul><li>The number of nodes in the graph is in the range&nbsp;<code>[0, 100]</code>.</li><li><code>1 &lt;= Node.val &lt;= 100</code></li><li><code>Node.val</code>&nbsp;is unique for each node.</li><li>There are no repeated edges and no self-loops in the graph.</li><li>The Graph is connected and all nodes can be visited starting from the given node.</li></ul>



<h2><strong>Solution: DFS + Hashtable</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png" alt="" class="wp-image-9776" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png" alt="" class="wp-image-9777" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png" alt="" class="wp-image-9778" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Time complexity: O(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:
  Node* cloneGraph(Node* node) {
    if (!node) return nullptr;
    unordered_map&lt;Node*, Node*&gt; m;
    function&lt;void(Node*)&gt; dfs = [&amp;](Node* u) {
      m[u] = new Node(u-&gt;val);
      for (Node* v : u-&gt;neighbors) {
        if (!m.count(v)) dfs(v);
        m[u]-&gt;neighbors.push_back(m[v]);
      }
    };
    dfs(node);
    return m[node];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/">花花酱 LeetCode 133. Clone 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-133-clone-graph-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 25 Jun 2022 23:07:42 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9761</guid>

					<description><![CDATA[<p>You are given an integer n. There is an undirected graph with n nodes, numbered from 0 to n - 1. You are given a 2D integer array edges where edges[i] = [ai, bi] denotes that there&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/">花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected 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[
<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 2316. Count Unreachable Pairs of Nodes in an Undirected Graph - 刷题找工作 EP397" width="500" height="281" src="https://www.youtube.com/embed/vH9CLfE82Rk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You are given an integer <code>n</code>. There is an <strong>undirected</strong> graph with <code>n</code> nodes, numbered from <code>0</code> to <code>n - 1</code>. You are given a 2D integer array <code>edges</code> where <code>edges[i] = [a<sub>i</sub>, b<sub>i</sub>]</code> denotes that there exists an <strong>undirected</strong> edge connecting nodes <code>a<sub>i</sub></code> and <code>b<sub>i</sub></code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>number of pairs</strong>&nbsp;of different nodes that are&nbsp;<strong>unreachable</strong>&nbsp;from each other</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/05/05/tc-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, edges = [[0,1],[0,2],[1,2]]
<strong>Output:</strong> 0
<strong>Explanation:</strong> There are no pairs of nodes that are unreachable from each other. Therefore, we return 0.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/05/05/tc-2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[0,2],[0,5],[2,4],[1,6],[5,4]]
<strong>Output:</strong> 14
<strong>Explanation:</strong> There are 14 pairs of nodes that are unreachable from each other:
[[0,1],[0,3],[0,6],[1,2],[1,3],[1,4],[1,5],[2,3],[2,6],[3,4],[3,5],[3,6],[4,6],[5,6]].
Therefore, we return 14.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= edges.length &lt;= 2 * 10<sup>5</sup></code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub>&nbsp;&lt; n</code></li><li><code>a<sub>i</sub>&nbsp;!= b<sub>i</sub></code></li><li>There are no repeated edges.</li></ul>



<h2><strong>Solution 1: DFS</strong></h2>



<p>Use DFS to find all CCs</p>



<p>Time complexity: O(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
// Author: Huahua, 791ms, 136 MB
class Solution {
public:
  long long countPairs(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    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; seen(n);
    long long cur = 0;
    
    function&lt;void(int)&gt; dfs = [&amp;](int u) {
      ++cur;
      for (int v : g[u])
        if (seen[v]++ == 0) dfs(v);      
    };
    long long ans = 0;    
    for (int i = 0; i &lt; n; ++i) {
      if (seen[i]++) continue;
      cur = 0;
      dfs(i);
      ans += (n - cur) * cur;
    }
    return ans / 2;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: Union Find</strong></h2>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  long long countPairs(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    vector&lt;int&gt; parents(n);
    vector&lt;int&gt; counts(n, 1);
    std::iota(begin(parents), end(parents), 0);
    
    function&lt;int(int)&gt; find = [&amp;](int x) {
      if (parents[x] == x) return x;
      return parents[x] = find(parents[x]);
    };
    
    for (const auto&amp; e : edges) {
      int ru = find(e[0]);
      int rv = find(e[1]);
      if (ru != rv) {
        parents[rv] = ru;
        counts[ru] += counts[rv];        
      }
    }
    long long ans = 0;    
    for (int i = 0; i &lt; n; ++i)      
      ans += n - counts[find(i)];
    return ans / 2;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/">花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected 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-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 12 Mar 2022 07:14:40 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9570</guid>

					<description><![CDATA[<p>You are given a positive integer&#160;n&#160;representing the number of nodes of a&#160;Directed Acyclic Graph&#160;(DAG). The nodes are numbered from&#160;0&#160;to&#160;n - 1&#160;(inclusive). You are also given&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/">花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic 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>You are given a positive integer&nbsp;<code>n</code>&nbsp;representing the number of nodes of a&nbsp;<strong>Directed Acyclic Graph</strong>&nbsp;(DAG). The nodes are numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;(<strong>inclusive</strong>).</p>



<p>You are also given a 2D integer array&nbsp;<code>edges</code>, where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>]</code>&nbsp;denotes that there is a&nbsp;<strong>unidirectional</strong>&nbsp;edge from&nbsp;<code>from<sub>i</sub></code>&nbsp;to&nbsp;<code>to<sub>i</sub></code>&nbsp;in the graph.</p>



<p>Return&nbsp;<em>a list</em>&nbsp;<code>answer</code><em>, where&nbsp;</em><code>answer[i]</code><em>&nbsp;is the&nbsp;<strong>list of ancestors</strong>&nbsp;of the</em>&nbsp;<code>i<sup>th</sup></code>&nbsp;<em>node, sorted in&nbsp;<strong>ascending order</strong></em>.</p>



<p>A node&nbsp;<code>u</code>&nbsp;is an&nbsp;<strong>ancestor</strong>&nbsp;of another node&nbsp;<code>v</code>&nbsp;if&nbsp;<code>u</code>&nbsp;can reach&nbsp;<code>v</code>&nbsp;via a set of edges.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]
<strong>Output:</strong> [[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]
<strong>Explanation:</strong>
The above diagram represents the input graph.
- Nodes 0, 1, and 2 do not have any ancestors.
- Node 3 has two ancestors 0 and 1.
- Node 4 has two ancestors 0 and 2.
- Node 5 has three ancestors 0, 1, and 3.
- Node 6 has five ancestors 0, 1, 2, 3, and 4.
- Node 7 has four ancestors 0, 1, 2, and 3.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edgeList = [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
<strong>Output:</strong> [[],[0],[0,1],[0,1,2],[0,1,2,3]]
<strong>Explanation:</strong>
The above diagram represents the input graph.
- Node 0 does not have any ancestor.
- Node 1 has one ancestor 0.
- Node 2 has two ancestors 0 and 1.
- Node 3 has three ancestors 0, 1, and 2.
- Node 4 has four ancestors 0, 1, 2, and 3.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 1000</code></li><li><code>0 &lt;= edges.length &lt;= min(2000, n * (n - 1) / 2)</code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= from<sub>i</sub>, to<sub>i</sub>&nbsp;&lt;= n - 1</code></li><li><code>from<sub>i</sub>&nbsp;!= to<sub>i</sub></code></li><li>There are no duplicate edges.</li><li>The graph is&nbsp;<strong>directed</strong>&nbsp;and&nbsp;<strong>acyclic</strong>.</li></ul>



<h2><strong>Solution: DFS</strong></h2>



<p>For each source node S, add it to all its reachable nodes by traversing the entire graph.<br>In one pass, only traverse each child node at most once.</p>



<p>Time complexity: O(VE)<br>Space complexity: (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:
  vector&lt;vector&lt;int&gt;&gt; getAncestors(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    vector&lt;vector&lt;int&gt;&gt; ans(n);
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges)
      g[e[0]].push_back(e[1]);    
    
    function&lt;void(int, int)&gt; dfs = [&amp;](int s, int u) -&gt; void {
      for (int v : g[u]) {
        if (ans[v].empty() || ans[v].back() != s) {
          ans[v].push_back(s);
          dfs(s, v);
        }
      }
    };
    
    for (int i = 0; i &lt; n; ++i)
      dfs(i, i);  
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/">花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic 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-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1998. GCD Sort of an Array</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 01 Jan 2022 06:49:23 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[gcd]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[prime]]></category>
		<category><![CDATA[sqrt]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9383</guid>

					<description><![CDATA[<p>You are given an integer array&#160;nums, and you can perform the following operation&#160;any&#160;number of times on&#160;nums: Swap the positions of two elements&#160;nums[i]&#160;and&#160;nums[j]&#160;if&#160;gcd(nums[i], nums[j]) &#62; 1&#160;where&#160;gcd(nums[i],&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/">花花酱 LeetCode 1998. GCD Sort of an Array</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 array&nbsp;<code>nums</code>, and you can perform the following operation&nbsp;<strong>any</strong>&nbsp;number of times on&nbsp;<code>nums</code>:</p>



<ul><li>Swap the positions of two elements&nbsp;<code>nums[i]</code>&nbsp;and&nbsp;<code>nums[j]</code>&nbsp;if&nbsp;<code>gcd(nums[i], nums[j]) &gt; 1</code>&nbsp;where&nbsp;<code>gcd(nums[i], nums[j])</code>&nbsp;is the&nbsp;<strong>greatest common divisor</strong>&nbsp;of&nbsp;<code>nums[i]</code>&nbsp;and&nbsp;<code>nums[j]</code>.</li></ul>



<p>Return&nbsp;<code>true</code>&nbsp;<em>if it is possible to sort&nbsp;</em><code>nums</code><em>&nbsp;in&nbsp;<strong>non-decreasing</strong>&nbsp;order using the above swap method, or&nbsp;</em><code>false</code><em>&nbsp;otherwise.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [7,21,3]
<strong>Output:</strong> true
<strong>Explanation:</strong> We can sort [7,21,3] by performing the following operations:
- Swap 7 and 21 because gcd(7,21) = 7. nums = [<strong>21</strong>,<strong>7</strong>,3]
- Swap 21 and 3 because gcd(21,3) = 3. nums = [<strong>3</strong>,7,<strong>21</strong>]
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [5,2,6,2]
<strong>Output:</strong> false
<strong>Explanation:</strong> It is impossible to sort the array because 5 cannot be swapped with any other element.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [10,5,9,3,15]
<strong>Output:</strong> true
We can sort [10,5,9,3,15] by performing the following operations:
- Swap 10 and 15 because gcd(10,15) = 5. nums = [<strong>15</strong>,5,9,3,<strong>10</strong>]
- Swap 15 and 3 because gcd(15,3) = 3. nums = [<strong>3</strong>,5,9,<strong>15</strong>,10]
- Swap 10 and 15 because gcd(10,15) = 5. nums = [3,5,9,<strong>10</strong>,<strong>15</strong>]
</pre>



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



<ul><li><code>1 &lt;= nums.length &lt;= 3 * 10<sup>4</sup></code></li><li><code>2 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Union-Find</strong></h2>



<p>Let nums[j]&#8217;s target position be i. In order to put nums[j] to pos i by swapping. nums[i] and nums[j] must be in the same connected component. There is an edge between two numbers if they have gcd > 1.</p>



<p>We union two numbers if their have gcd > 1. However, it will be TLE if we do all pairs . Thus, for each number, we union it with its divisors instead.</p>



<p>Time complexity: O(n<sup>2</sup>) TLE -> O(sum(sqrt(nums[i]))) &lt;= O(n*sqrt(m))<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:
  bool gcdSort(vector&lt;int&gt;&amp; nums) {
    const int m = *max_element(begin(nums), end(nums));
    const int n = nums.size();
    
    vector&lt;int&gt; p(m + 1);
    iota(begin(p), end(p), 0);
  
    function&lt;int(int)&gt; find = [&amp;](int x) {
      return p[x] == x ? x : (p[x] = find(p[x]));
    };
  
    for (int x : nums)
      for (int d = 2; d &lt;= sqrt(x); ++d)
        if (x % d == 0)
          p[find(x)] = p[find(x / d)] = find(d);

    vector&lt;int&gt; sorted(nums);
    sort(begin(sorted), end(sorted));
    
    for (int i = 0; i &lt; n; ++i)
      if (find(sorted[i]) != find(nums[i])) 
        return false;

    return true;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/">花花酱 LeetCode 1998. GCD Sort of an Array</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-1998-gcd-sort-of-an-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2097. Valid Arrangement of Pairs</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Dec 2021 17:36:35 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[eulerian]]></category>
		<category><![CDATA[graph]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9032</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;2D integer array&#160;pairs&#160;where&#160;pairs[i] = [starti, endi]. An arrangement of&#160;pairs&#160;is&#160;valid&#160;if for every index&#160;i&#160;where&#160;1 &#60;= i &#60; pairs.length, we have&#160;endi-1&#160;== starti. Return&#160;any&#160;valid arrangement of&#160;pairs.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/">花花酱 LeetCode 2097. Valid Arrangement of Pairs</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>pairs</code>&nbsp;where&nbsp;<code>pairs[i] = [start<sub>i</sub>, end<sub>i</sub>]</code>. An arrangement of&nbsp;<code>pairs</code>&nbsp;is&nbsp;<strong>valid</strong>&nbsp;if for every index&nbsp;<code>i</code>&nbsp;where&nbsp;<code>1 &lt;= i &lt; pairs.length</code>, we have&nbsp;<code>end<sub>i-1</sub>&nbsp;== start<sub>i</sub></code>.</p>



<p>Return&nbsp;<em><strong>any</strong>&nbsp;valid arrangement of&nbsp;</em><code>pairs</code>.</p>



<p><strong>Note:</strong>&nbsp;The inputs will be generated such that there exists a valid arrangement of&nbsp;<code>pairs</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[5,1],[4,5],[11,9],[9,4]]
<strong>Output:</strong> [[11,9],[9,4],[4,5],[5,1]]
<strong>Explanation:
</strong>This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 9 == 9 = start<sub>1</sub> 
end<sub>1</sub> = 4 == 4 = start<sub>2</sub>
end<sub>2</sub> = 5 == 5 = start<sub>3</sub>
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[1,3],[3,2],[2,1]]
<strong>Output:</strong> [[1,3],[3,2],[2,1]]
<strong>Explanation:</strong>
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 3 == 3 = start<sub>1</sub>
end<sub>1</sub> = 2 == 2 = start<sub>2</sub>
The arrangements [[2,1],[1,3],[3,2]] and [[3,2],[2,1],[1,3]] are also valid.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[1,2],[1,3],[2,1]]
<strong>Output:</strong> [[1,2],[2,1],[1,3]]
<strong>Explanation:</strong>
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 2 == 2 = start<sub>1</sub>
end<sub>1</sub> = 1 == 1 = start<sub>2</sub>
</pre>



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



<ul><li><code>1 &lt;= pairs.length &lt;= 10<sup>5</sup></code></li><li><code>pairs[i].length == 2</code></li><li><code>0 &lt;= start<sub>i</sub>, end<sub>i</sub>&nbsp;&lt;= 10<sup>9</sup></code></li><li><code>start<sub>i</sub>&nbsp;!= end<sub>i</sub></code></li><li>No two pairs are exactly the same.</li><li>There&nbsp;<strong>exists</strong>&nbsp;a valid arrangement of&nbsp;<code>pairs</code>.</li></ul>



<h2><strong>Solution: Eulerian trail</strong></h2>



<p>The goal of the problem is to find a Eulerian trail in the graph.</p>



<p>If there is a vertex whose out degree &#8211; in degree == 1 which means it&#8217;s the starting vertex. Otherwise wise, the graph must have a Eulerian circuit thus we can start from any vertex.</p>



<p>We can use Hierholzer&#8217;s algorithm to find it.</p>



<p>Time complexity: O(|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:
  vector&lt;vector&lt;int&gt;&gt; validArrangement(vector&lt;vector&lt;int&gt;&gt;&amp; pairs) {    
    unordered_map&lt;int, queue&lt;int&gt;&gt; g;
    unordered_map&lt;int, int&gt; degree; // out - in  
    for (const auto&amp; p : pairs) {
      g[p[0]].push(p[1]);
      ++degree[p[0]];
      --degree[p[1]];
    }
    
    int s = pairs[0][0];
    for (const auto&amp; [u, d] : degree)
      if (d == 1) s = u;
    
    vector&lt;vector&lt;int&gt;&gt; ans;
    function&lt;void(int)&gt; dfs = [&amp;](int u) {
      while (!g[u].empty()) {
        int v = g[u].front(); g[u].pop();
        dfs(v);
        ans.push_back({u, v});
      }
    };
    dfs(s);
    return {rbegin(ans), rend(ans)};
  }
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def validArrangement(self, pairs: List[List[int]]) -&gt; List[List[int]]:
    g = defaultdict(list)
    d = defaultdict(int)
    for u, v in pairs:
      g[u].append(v)
      d[u] += 1
      d[v] -= 1
    
    s = pairs[0][0]
    for u in d:
      if d[u] == 1: s = u
    
    ans = []
    def dfs(u: int) -&gt; None:
      while g[u]:
        v = g[u].pop()
        dfs(v)
        ans.append([u, v])

    dfs(s)
    return ans[::-1]</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/">花花酱 LeetCode 2097. Valid Arrangement of Pairs</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-2097-valid-arrangement-of-pairs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2092. Find All People With Secret</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2092-find-all-people-with-secret/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2092-find-all-people-with-secret/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Nov 2021 17:44:35 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8859</guid>

					<description><![CDATA[<p>You are given an integer&#160;n&#160;indicating there are&#160;n&#160;people numbered from&#160;0&#160;to&#160;n - 1. You are also given a&#160;0-indexed&#160;2D integer array&#160;meetings&#160;where&#160;meetings[i] = [xi, yi, timei]&#160;indicates that person&#160;xi&#160;and person&#160;yi&#160;have&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2092-find-all-people-with-secret/">花花酱 LeetCode 2092. Find All People With Secret</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&nbsp;<code>n</code>&nbsp;indicating there are&nbsp;<code>n</code>&nbsp;people numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>meetings</code>&nbsp;where&nbsp;<code>meetings[i] = [x<sub>i</sub>, y<sub>i</sub>, time<sub>i</sub>]</code>&nbsp;indicates that person&nbsp;<code>x<sub>i</sub></code>&nbsp;and person&nbsp;<code>y<sub>i</sub></code>&nbsp;have a meeting at&nbsp;<code>time<sub>i</sub></code>. A person may attend&nbsp;<strong>multiple meetings</strong>&nbsp;at the same time. Finally, you are given an integer&nbsp;<code>firstPerson</code>.</p>



<p>Person&nbsp;<code>0</code>&nbsp;has a&nbsp;<strong>secret</strong>&nbsp;and initially shares the secret with a person&nbsp;<code>firstPerson</code>&nbsp;at time&nbsp;<code>0</code>. This secret is then shared every time a meeting takes place with a person that has the secret. More formally, for every meeting, if a person&nbsp;<code>x<sub>i</sub></code>&nbsp;has the secret at&nbsp;<code>time<sub>i</sub></code>, then they will share the secret with person&nbsp;<code>y<sub>i</sub></code>, and vice versa.</p>



<p>The secrets are shared&nbsp;<strong>instantaneously</strong>. That is, a person may receive the secret and share it with people in other meetings within the same time frame.</p>



<p>Return&nbsp;<em>a list of all the people that have the secret after all the meetings have taken place.&nbsp;</em>You may return the answer in&nbsp;<strong>any order</strong>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 6, meetings = [[1,2,5],[2,3,8],[1,5,10]], firstPerson = 1
<strong>Output:</strong> [0,1,2,3,5]
<strong>Explanation:
</strong>At time 0, person 0 shares the secret with person 1.
At time 5, person 1 shares the secret with person 2.
At time 8, person 2 shares the secret with person 3.
At time 10, person 1 shares the secret with person 5.​​​​
Thus, people 0, 1, 2, 3, and 5 know the secret after all the meetings.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, meetings = [[3,1,3],[1,2,2],[0,3,3]], firstPerson = 3
<strong>Output:</strong> [0,1,3]
<strong>Explanation:</strong>
At time 0, person 0 shares the secret with person 3.
At time 2, neither person 1 nor person 2 know the secret.
At time 3, person 3 shares the secret with person 0 and person 1.
Thus, people 0, 1, and 3 know the secret after all the meetings.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, meetings = [[3,4,2],[1,2,1],[2,3,1]], firstPerson = 1
<strong>Output:</strong> [0,1,2,3,4]
<strong>Explanation:</strong>
At time 0, person 0 shares the secret with person 1.
At time 1, person 1 shares the secret with person 2, and person 2 shares the secret with person 3.
Note that person 2 can share the secret at the same time as receiving it.
At time 2, person 3 shares the secret with person 4.
Thus, people 0, 1, 2, 3, and 4 know the secret after all the meetings.
</pre>



<p><strong>Example 4:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 6, meetings = [[0,2,1],[1,3,1],[4,5,1]], firstPerson = 1
<strong>Output:</strong> [0,1,2,3]
<strong>Explanation:</strong>
At time 0, person 0 shares the secret with person 1.
At time 1, person 0 shares the secret with person 2, and person 1 shares the secret with person 3.
Thus, people 0, 1, 2, and 3 know the secret after all the meetings.
</pre>



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



<ul><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= meetings.length &lt;= 10<sup>5</sup></code></li><li><code>meetings[i].length == 3</code></li><li><code>0 &lt;= x<sub>i</sub>, y<sub>i&nbsp;</sub>&lt;= n - 1</code></li><li><code>x<sub>i</sub>&nbsp;!= y<sub>i</sub></code></li><li><code>1 &lt;= time<sub>i</sub>&nbsp;&lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= firstPerson &lt;= n - 1</code></li></ul>



<h2><strong>Solution: Union Find</strong></h2>



<p>Sorting meetings by time.</p>



<p>At each time stamp, union people who meet.<br>Key step: &#8220;<strong><span class="has-inline-color has-vivid-red-color">un-union</span></strong>&#8221; people if they <strong><span class="has-inline-color has-vivid-red-color">DO NOT</span></strong> connected to 0 / known the secret after each timestamp.</p>



<p>Time complexity: O(nlogn + 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;int&gt; findAllPeople(int n, vector&lt;vector&lt;int&gt;&gt;&amp; meetings, int firstPerson) {        
    map&lt;int, vector&lt;pair&lt;int, int&gt;&gt;&gt; events;
    for (const auto&amp; m : meetings)
      events[m[2]].emplace_back(m[0], m[1]);
    vector&lt;int&gt; p(n);
    iota(begin(p), end(p), 0);
    function&lt;int(int)&gt; find = [&amp;](int x) {
      return p[x] == x ? x : (p[x] = find(p[x]));
    };
    p[firstPerson] = 0;
    for (const auto&amp; [t, s] : events) {
      for (const auto [u, v] : s)
        p[find(u)] = find(v);
      for (const auto [u, v] : s) {
        if (find(u) != find(0)) p[u] = u;
        if (find(v) != find(0)) p[v] = v;
      }
    }    
    vector&lt;int&gt; ans;
    for (int i = 0; i &lt; n; ++i)
      if (find(i) == find(0)) ans.push_back(i);
    return ans;
  }
};</pre>
</div></div>



<h2><strong>Related Problems</strong></h2>



<ul><li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-1202-smallest-string-with-swaps/">花花酱 LeetCode 1202. Smallest String With Swaps</a></li><li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/" data-type="post" data-id="6962">花花酱 LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree</a></li><li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-2076-process-restricted-friend-requests/" data-type="post" data-id="8719">花花酱 LeetCode 2076. Process Restricted Friend Requests</a></li><li><a href="https://zxi.mytechroad.com/blog/uncategorized/leetcode-1722-minimize-hamming-distance-after-swap-operations/" data-type="post" data-id="7967">花花酱 LeetCode 1722. Minimize Hamming Distance After Swap Operations</a></li><li><a href="https://zxi.mytechroad.com/blog/data-structure/sp1-union-find-set/" data-type="post" data-id="1039">花花酱 LeetCode Disjoint set / Union Find Forest SP1</a></li></ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2092-find-all-people-with-secret/">花花酱 LeetCode 2092. Find All People With Secret</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-2092-find-all-people-with-secret/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2050. Parallel Courses III</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 19 Nov 2021 03:31:15 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8722</guid>

					<description><![CDATA[<p>You are given an integer&#160;n, which indicates that there are&#160;n&#160;courses labeled from&#160;1&#160;to&#160;n. You are also given a 2D integer array&#160;relations&#160;where&#160;relations[j] = [prevCoursej, nextCoursej]&#160;denotes that course&#160;prevCoursej&#160;has&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/">花花酱 LeetCode 2050. Parallel Courses III</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&nbsp;<code>n</code>, which indicates that there are&nbsp;<code>n</code>&nbsp;courses labeled from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. You are also given a 2D integer array&nbsp;<code>relations</code>&nbsp;where&nbsp;<code>relations[j] = [prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code>&nbsp;denotes that course&nbsp;<code>prevCourse<sub>j</sub></code>&nbsp;has to be completed&nbsp;<strong>before</strong>&nbsp;course&nbsp;<code>nextCourse<sub>j</sub></code>&nbsp;(prerequisite relationship). Furthermore, you are given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>time</code>&nbsp;where&nbsp;<code>time[i]</code>&nbsp;denotes how many&nbsp;<strong>months</strong>&nbsp;it takes to complete the&nbsp;<code>(i+1)<sup>th</sup></code>&nbsp;course.</p>



<p>You must find the&nbsp;<strong>minimum</strong>&nbsp;number of months needed to complete all the courses following these rules:</p>



<ul><li>You may start taking a course at&nbsp;<strong>any time</strong>&nbsp;if the prerequisites are met.</li><li><strong>Any number of courses</strong>&nbsp;can be taken at the&nbsp;<strong>same time</strong>.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;number of months needed to complete all the courses</em>.</p>



<p><strong>Note:</strong>&nbsp;The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).</p>



<p><strong>Example 1:</strong><strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex1.png"></strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
<strong>Output:</strong> 8
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course. 
We start course 1 and course 2 simultaneously at month 0.
Course 1 takes 3 months and course 2 takes 2 months to complete respectively.
Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.
</pre>



<p><strong>Example 2:</strong><strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex2.png"></strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5]
<strong>Output:</strong> 12
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
You can start courses 1, 2, and 3 at month 0.
You can complete them after 1, 2, and 3 months respectively.
Course 4 can be taken only after course 3 is completed, i.e., after 3 months. It is completed after 3 + 4 = 7 months.
Course 5 can be taken only after courses 1, 2, 3, and 4 have been completed, i.e., after max(1,2,3,7) = 7 months.
Thus, the minimum time needed to complete all the courses is 7 + 5 = 12 months.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 5 * 10<sup>4</sup></code></li><li><code>0 &lt;= relations.length &lt;= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code></li><li><code>relations[j].length == 2</code></li><li><code>1 &lt;= prevCourse<sub>j</sub>, nextCourse<sub>j</sub>&nbsp;&lt;= n</code></li><li><code>prevCourse<sub>j</sub>&nbsp;!= nextCourse<sub>j</sub></code></li><li>All the pairs&nbsp;<code>[prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code>&nbsp;are&nbsp;<strong>unique</strong>.</li><li><code>time.length == n</code></li><li><code>1 &lt;= time[i] &lt;= 10<sup>4</sup></code></li><li>The given graph is a directed acyclic graph.</li></ul>



<h2><strong>Solution: Topological Sorting</strong></h2>



<p>Time complexity: O(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 minimumTime(int n, vector&lt;vector&lt;int&gt;&gt;&amp; relations, vector&lt;int&gt;&amp; time) {
    vector&lt;vector&lt;int&gt;&gt; g(n);  
    for (const auto&amp; r: relations)
      g[r[0] - 1].push_back(r[1] - 1);    
    vector&lt;int&gt; t(n, -1);
    function&lt;int(int)&gt; dfs = [&amp;](int u) {
      if (t[u] != -1) return t[u];
      t[u] = 0;
      for (int v : g[u])
        t[u] = max(t[u], dfs(v));
      return t[u] += time[u];
    };
    int ans = 0;
    for (int i = 0; i &lt; n; ++i)
      ans = max(ans, dfs(i));
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag">class Solution:
  def minimumTime(self, n: int, relations: List[List[int]], time: List[int]) -&gt; int:
    g = [[] for _ in range(n)]
    for u, v in relations: g[u - 1].append(v - 1)
    @cache
    def dfs(u: int) -&gt; int:      
      return max([dfs(v) for v in g[u]] + [0]) + time[u]
    return max(dfs(u) for u in range(n))</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/">花花酱 LeetCode 2050. Parallel Courses III</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-2050-parallel-courses-iii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2076. Process Restricted Friend Requests</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2076-process-restricted-friend-requests/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2076-process-restricted-friend-requests/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 15 Nov 2021 21:04:13 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8719</guid>

					<description><![CDATA[<p>You are given an integer&#160;n&#160;indicating the number of people in a network. Each person is labeled from&#160;0&#160;to&#160;n - 1. You are also given a&#160;0-indexed&#160;2D integer&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2076-process-restricted-friend-requests/">花花酱 LeetCode 2076. Process Restricted Friend Requests</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&nbsp;<code>n</code>&nbsp;indicating the number of people in a network. Each person is labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>.</p>



<p>You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>restrictions</code>, where&nbsp;<code>restrictions[i] = [x<sub>i</sub>, y<sub>i</sub>]</code>&nbsp;means that person&nbsp;<code>x<sub>i</sub></code>&nbsp;and person&nbsp;<code>y<sub>i</sub></code>&nbsp;<strong>cannot&nbsp;</strong>become&nbsp;<strong>friends</strong>,either&nbsp;<strong>directly</strong>&nbsp;or&nbsp;<strong>indirectly</strong>&nbsp;through other people.</p>



<p>Initially, no one is friends with each other. You are given a list of friend requests as a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>requests</code>, where&nbsp;<code>requests[j] = [u<sub>j</sub>, v<sub>j</sub>]</code>&nbsp;is a friend request between person&nbsp;<code>u<sub>j</sub></code>&nbsp;and person&nbsp;<code>v<sub>j</sub></code>.</p>



<p>A friend request is&nbsp;<strong>successful&nbsp;</strong>if&nbsp;<code>u<sub>j</sub></code>&nbsp;and&nbsp;<code>v<sub>j</sub></code>&nbsp;can be&nbsp;<strong>friends</strong>. Each friend request is processed in the given order (i.e.,&nbsp;<code>requests[j]</code>&nbsp;occurs before&nbsp;<code>requests[j + 1]</code>), and upon a successful request,&nbsp;<code>u<sub>j</sub></code>&nbsp;and&nbsp;<code>v<sub>j</sub></code>&nbsp;<strong>become direct friends</strong>&nbsp;for all future friend requests.</p>



<p>Return&nbsp;<em>a&nbsp;<strong>boolean array</strong>&nbsp;</em><code>result</code>,<em>&nbsp;where each&nbsp;</em><code>result[j]</code><em>&nbsp;is&nbsp;</em><code>true</code><em>&nbsp;if the&nbsp;</em><code>j<sup>th</sup></code><em>&nbsp;friend request is&nbsp;<strong>successful</strong>&nbsp;or&nbsp;</em><code>false</code><em>&nbsp;if it is not</em>.</p>



<p><strong>Note:</strong>&nbsp;If&nbsp;<code>u<sub>j</sub></code>&nbsp;and&nbsp;<code>v<sub>j</sub></code>&nbsp;are already direct friends, the request is still&nbsp;<strong>successful</strong>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, restrictions = [[0,1]], requests = [[0,2],[2,1]]
<strong>Output:</strong> [true,false]
<strong>Explanation:
</strong>Request 0: Person 0 and person 2 can be friends, so they become direct friends. 
Request 1: Person 2 and person 1 cannot be friends since person 0 and person 1 would be indirect friends (1--2--0).
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, restrictions = [[0,1]], requests = [[1,2],[0,2]]
<strong>Output:</strong> [true,false]
<strong>Explanation:
</strong>Request 0: Person 1 and person 2 can be friends, so they become direct friends.
Request 1: Person 0 and person 2 cannot be friends since person 0 and person 1 would be indirect friends (0--2--1).
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, restrictions = [[0,1],[1,2],[2,3]], requests = [[0,4],[1,2],[3,1],[3,4]]
<strong>Output:</strong> [true,false,true,false]
<strong>Explanation:
</strong>Request 0: Person 0 and person 4 can be friends, so they become direct friends.
Request 1: Person 1 and person 2 cannot be friends since they are directly restricted.
Request 2: Person 3 and person 1 can be friends, so they become direct friends.
Request 3: Person 3 and person 4 cannot be friends since person 0 and person 1 would be indirect friends (0--4--3--1).
</pre>



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



<ul><li><code>2 &lt;= n &lt;= 1000</code></li><li><code>0 &lt;= restrictions.length &lt;= 1000</code></li><li><code>restrictions[i].length == 2</code></li><li><code>0 &lt;= x<sub>i</sub>, y<sub>i</sub>&nbsp;&lt;= n - 1</code></li><li><code>x<sub>i</sub>&nbsp;!= y<sub>i</sub></code></li><li><code>1 &lt;= requests.length &lt;= 1000</code></li><li><code>requests[j].length == 2</code></li><li><code>0 &lt;= u<sub>j</sub>, v<sub>j</sub>&nbsp;&lt;= n - 1</code></li><li><code>u<sub>j</sub>&nbsp;!= v<sub>j</sub></code></li></ul>



<p><strong>Solution: Union Find / Brute Force</strong></p>



<p>For each request, check all restrictions.</p>



<p>Time complexity: O(req * res)<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:
  vector&lt;bool&gt; friendRequests(int n, vector&lt;vector&lt;int&gt;&gt;&amp; restrictions, vector&lt;vector&lt;int&gt;&gt;&amp; requests) {
    vector&lt;int&gt; parents(n);
    iota(begin(parents), end(parents), 0);
    function&lt;int(int)&gt; find = [&amp;](int x) {
      if (parents[x] == x) return x;
      return parents[x] = find(parents[x]);
    };
    auto check = [&amp;](int u, int v) {
      for (const auto&amp; r : restrictions) {
        int pu = find(r[0]);
        int pv = find(r[1]);
        if ((pu == u &amp;&amp; pv == v) || (pu == v &amp;&amp; pv == u))
          return false;
      }
      return true;
    };
    vector&lt;bool&gt; ans;
    for (const auto&amp; r : requests) {      
      int pu = find(r[0]);
      int pv = find(r[1]);
      if (pu == pv || check(pu, pv)) {
        parents[pu] = pv;
        ans.push_back(true);
      } else {
        ans.push_back(false);
      }
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2076-process-restricted-friend-requests/">花花酱 LeetCode 2076. Process Restricted Friend Requests</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-2076-process-restricted-friend-requests/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
