<?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>MST Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/mst/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/mst/</link>
	<description></description>
	<lastBuildDate>Sun, 13 Sep 2020 07:46:41 +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>MST Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/mst/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1584. Min Cost to Connect All Points</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1584-min-cost-to-connect-all-points/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1584-min-cost-to-connect-all-points/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 13 Sep 2020 07:22:16 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[MST]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7367</guid>

					<description><![CDATA[<p>You are given an array&#160;points&#160;representing integer coordinates of some points on a 2D-plane, where&#160;points[i] = [xi, yi]. The cost of connecting two points&#160;[xi, yi]&#160;and&#160;[xj, yj]&#160;is&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1584-min-cost-to-connect-all-points/">花花酱 LeetCode 1584. Min Cost to Connect All Points</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 array&nbsp;<code>points</code>&nbsp;representing integer coordinates of some points on a 2D-plane, where&nbsp;<code>points[i] = [x<sub>i</sub>, y<sub>i</sub>]</code>.</p>



<p>The cost of connecting two points&nbsp;<code>[x<sub>i</sub>, y<sub>i</sub>]</code>&nbsp;and&nbsp;<code>[x<sub>j</sub>, y<sub>j</sub>]</code>&nbsp;is the&nbsp;<strong>manhattan distance</strong>&nbsp;between them:&nbsp;<code>|x<sub>i</sub>&nbsp;- x<sub>j</sub>| + |y<sub>i</sub>&nbsp;- y<sub>j</sub>|</code>, where&nbsp;<code>|val|</code>&nbsp;denotes the absolute value of&nbsp;<code>val</code>.</p>



<p>Return&nbsp;<em>the minimum cost to make all points connected.</em>&nbsp;All points are connected if there is&nbsp;<strong>exactly one</strong>&nbsp;simple path between any two points.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/26/d.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
<strong>Output:</strong> 20
<strong>Explanation:
</strong>
We can connect the points as shown above to get the minimum cost of 20.
Notice that there is a unique path between every pair of points.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> points = [[3,12],[-2,5],[-4,1]]
<strong>Output:</strong> 18
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> points = [[0,0],[1,1],[1,0],[-1,1]]
<strong>Output:</strong> 4
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> points = [[-1000000,-1000000],[1000000,1000000]]
<strong>Output:</strong> 4000000
</pre>



<p><strong>Example 5:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> points = [[0,0]]
<strong>Output:</strong> 0
</pre>



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



<ul><li><code>1 &lt;= points.length &lt;= 1000</code></li><li><code>-10<sup>6</sup>&nbsp;&lt;= x<sub>i</sub>, y<sub>i</sub>&nbsp;&lt;= 10<sup>6</sup></code></li><li>All pairs&nbsp;<code>(x<sub>i</sub>, y<sub>i</sub>)</code>&nbsp;are distinct.</li></ul>



<h2><strong>Solution: Minimum Spanning Tree</strong></h2>



<p>Kruskal&#8217;s algorithm <br>Time complexity: O(n^2logn) <br>Space complexity: O(n^2)<br>using vector of vector, array, pair of pair, or tuple might lead to TLE&#8230;</p>



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

<pre class="crayon-plain-tag">struct Edge {
  int cost;
  int x;
  int y;
  bool operator&lt;(const Edge&amp; e) const { return cost &lt; e.cost; }
};
class Solution {
public:
  int minCostConnectPoints(vector&lt;vector&lt;int&gt;&gt;&amp; points) {
    const int n = points.size();
    vector&lt;Edge&gt; edges(n * (n - 1) / 2); // {cost, i, j}
    for (int i = 0, idx = 0; i &lt; n; ++i)
      for (int j = i + 1; j &lt; n; ++j)
        edges[idx++] = {abs(points[i][0] - points[j][0]) + 
                        abs(points[i][1] - points[j][1]), i, j};
    std::sort(begin(edges), end(edges));
    vector&lt;int&gt; p(n); 
    std::iota(begin(p), end(p), 0);
    vector&lt;int&gt; rank(n, 0);
    int ans = 0;
    int count = 0;
    for (const auto&amp; e : edges) {          
      int rx = find(p, e.x);
      int ry = find(p, e.y);
      if (rx == ry) continue;
      ans += e.cost;
      if (rank[rx] &lt; rank[ry]) swap(rx, ry);
      p[rx] = ry;
      rank[ry] += rank[rx] == rank[ry];
      if (++count == n - 1) break;
    }
    return ans;
  }
private:
  int find(vector&lt;int&gt;&amp; p, int x) const {   
    while (p[x] != x) {
      int tp = p[x];
      p[x] = p[p[x]];
      x = tp;
    }
    return x;
  }
};</pre>
</div></div>



<p>Prim&#8217;s Algorithm <br>ds[i] := min distance from i to <strong>ANY</strong> nodes in the tree.</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int minCostConnectPoints(vector&lt;vector&lt;int&gt;&gt;&amp; points) {
    const int n = points.size();
    auto dist = [](const vector&lt;int&gt;&amp; pi, const vector&lt;int&gt;&amp; pj) {
      return abs(pi[0] - pj[0]) + abs(pi[1] - pj[1]);
    };
    vector&lt;int&gt; ds(n, INT_MAX);  
    for (int i = 1; i &lt; n; ++i)
      ds[i] = dist(points[0], points[i]);
    
    int ans = 0;
    for (int i = 1; i &lt; n; ++i) {
      auto it = min_element(begin(ds), end(ds));
      const int v = distance(begin(ds), it);
      ans += ds[v];      
      ds[v] = INT_MAX; // done
      for (int i = 0; i &lt; n; ++i) {
        if (ds[i] == INT_MAX) continue;
        ds[i] = min(ds[i], dist(points[i], points[v]));
      }        
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1584-min-cost-to-connect-all-points/">花花酱 LeetCode 1584. Min Cost to Connect All Points</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-1584-min-cost-to-connect-all-points/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 27 Jun 2020 05:33:39 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[MST]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6962</guid>

					<description><![CDATA[<p>Given a weighted undirected connected graph with&#160;n&#160;vertices numbered from&#160;0&#160;to&#160;n-1,&#160;and an array&#160;edges&#160;where&#160;edges[i] = [fromi, toi, weighti]&#160;represents a bidirectional and weighted edge between nodes&#160;fromi&#160;and&#160;toi. A minimum spanning&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/">花花酱 LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree - 刷题找工作 EP338" width="500" height="281" src="https://www.youtube.com/embed/GzPUvV85kBI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a weighted undirected connected graph with&nbsp;<code>n</code>&nbsp;vertices numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n-1</code>,&nbsp;and an array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>, weight<sub>i</sub>]</code>&nbsp;represents a bidirectional and weighted edge between nodes&nbsp;<code>from<sub>i</sub></code>&nbsp;and&nbsp;<code>to<sub>i</sub></code>. A minimum spanning tree (MST) is a subset of the edges of the graph that connects all vertices without cycles&nbsp;and with the minimum possible total edge weight.</p>



<p>Find&nbsp;<em>all the critical and pseudo-critical edges in the minimum spanning tree (MST) of the given graph</em>. An MST edge whose deletion from the graph would cause the MST weight to increase is called a&nbsp;<em>critical edge</em>. A&nbsp;<em>pseudo-critical edge</em>, on the other hand, is that which can appear in some MSTs but not all.</p>



<p>Note that you can return the indices of the edges in any order.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/06/04/ex1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edges = [[0,1,1],[1,2,1],[2,3,2],[0,3,2],[0,4,3],[3,4,3],[1,4,6]]
<strong>Output:</strong> [[0,1],[2,3,4,5]]
<strong>Explanation:</strong> The figure above describes the graph.
The following figure shows all the possible MSTs:

Notice that the two edges 0 and 1 appear in all MSTs, therefore they are critical edges, so we return them in the first list of the output.
The edges 2, 3, 4, and 5 are only part of some MSTs, therefore they are considered pseudo-critical edges. We add them to the second list of the output.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/06/04/ex2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, edges = [[0,1,1],[1,2,1],[2,3,1],[0,3,1]]
<strong>Output:</strong> [[],[0,1,2,3]]
<strong>Explanation:</strong> We can observe that since all 4 edges have equal weight, choosing any 3 edges from the given 4 will yield an MST. Therefore all 4 edges are pseudo-critical.
</pre>



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



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



<h2><strong>Solution: Brute Force?</strong></h2>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/06/1489-ep338.png" alt="" class="wp-image-6967" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/06/1489-ep338.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/06/1489-ep338-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/06/1489-ep338-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>For each edge<br>1. exclude it and build a MST, cost increased =&gt; critical<br>2. for a non critical edge, force include it and build a MST, cost remains the same =&gt; pseudo critical</p>



<p>Proof of 2, if a non critical / non pseudo critical edge was added into the MST, the total cost must be increased. So if the cost remains the same, must be the other case. Since we know the edge is non-critical, so it has to be pseudo critical.</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class UnionFind {
 public:
  explicit UnionFind(int n): p_(n), r_(n) { iota(begin(p_), end(p_), 0); } // e.g. p[i] = i
  int Find(int x) { return p_[x] == x ? x : p_[x] = Find(p_[x]); }
  bool Union(int x, int y) {
    int rx = Find(x);
    int ry = Find(y);
    if (rx == ry) return false;
    if (r_[rx] == r_[ry]) {
      p_[rx] = ry;
      ++r_[ry];
    } else if (r_[rx] &gt; r_[ry]) {
      p_[ry] = rx;
    } else {
      p_[rx] = ry;
    }    
    return true;
  }
 private:
  vector&lt;int&gt; p_, r_;  
};

class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; findCriticalAndPseudoCriticalEdges(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    // Record the original id.
    for (int i = 0; i &lt; edges.size(); ++i) edges[i].push_back(i);
    // Sort edges by weight.
    sort(begin(edges), end(edges), [&amp;](const auto&amp; e1, const auto&amp; e2){
      if (e1[2] != e2[2]) return e1[2] &lt; e2[2];        
      return e1 &lt; e2;
    });
    // Cost of MST, ex: edge to exclude, in: edge to include.
    auto MST = [&amp;](int ex = -1, int in = -1) -&gt; int {
      UnionFind uf(n);
      int cost = 0;
      int count = 0;
      if (in &gt;= 0) {
        cost += edges[in][2];
        uf.Union(edges[in][0], edges[in][1]);
        count++;
      }
      for (int i = 0; i &lt; edges.size(); ++i) {        
        if (i == ex) continue;
        if (!uf.Union(edges[i][0], edges[i][1])) continue;
        cost += edges[i][2];
        ++count;
      }
      return count == n - 1 ? cost : INT_MAX;
    };
    const int min_cost = MST();
    vector&lt;int&gt; criticals;
    vector&lt;int&gt; pseudos;
    for (int i = 0; i &lt; edges.size(); ++i) {
      // Cost increased or can't form a tree.
      if (MST(i) &gt; min_cost) {
        criticals.push_back(edges[i][3]);
      } else if (MST(-1, i) == min_cost) {
        pseudos.push_back(edges[i][3]);
      }
    }
    return {criticals, pseudos};
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/">花花酱 LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree</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-1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 Minimum Spanning Tree (MST) 最小生成树 SP18</title>
		<link>https://zxi.mytechroad.com/blog/sp/minimum-spanning-tree-sp18/</link>
					<comments>https://zxi.mytechroad.com/blog/sp/minimum-spanning-tree-sp18/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 24 Jan 2020 15:59:23 +0000</pubDate>
				<category><![CDATA[SP]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[MST]]></category>
		<category><![CDATA[O(ElogV)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6124</guid>

					<description><![CDATA[<p>Prim&#8217;s Algorithm Time complexity: O(ElogV)Space complexity: O(V+E) [crayon-663c60f861cf8049530406/] [crayon-663c60f861cfc671816316/] Kruskal&#8217;s Algorithm Time complexity: O(ElogV)Space complexity: O(V+E) [crayon-663c60f861cfe124622326/] [crayon-663c60f861cff060863402/]</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/sp/minimum-spanning-tree-sp18/">花花酱 Minimum Spanning Tree (MST) 最小生成树 SP18</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode - 最小生成树 (Minimum Spanning Tree) 刷题找工作 SP18" width="500" height="281" src="https://www.youtube.com/embed/wmW8G8SrXDs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<h2><strong>Prim&#8217;s Algorithm</strong></h2>



<p>Time complexity: O(ElogV)<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
#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;vector&gt;
using namespace std;

int main(int argc, char** argv) {
  const int n = 4;
  vector&lt;vector&lt;int&gt;&gt; edges{{0,1,1},{0,3,3},{0,2,6},{2,3,2},{1,2,4},{1,3,5}};
  vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(n);
  for (const auto&amp; e : edges) {
    g[e[0]].emplace_back(e[1], e[2]);
    g[e[1]].emplace_back(e[0], e[2]);
  }

  priority_queue&lt;pair&lt;int, int&gt;&gt; q; // (-w, v)
  vector&lt;int&gt; seen(n);
  q.emplace(0, 0); // (-w, v)

  int cost = 0;
  for (int i = 0; i &lt; n; ++i) {
    while (true) {
      const int w = -q.top().first;
      const int v = q.top().second;
      q.pop();
      if (seen[v]++) continue;
      cost += w;
      for (const auto&amp; p : g[v]) {
        if (seen[p.first]) continue;
        q.emplace(-p.second, p.first);
      }
      break;
    }
  }
  cout &lt;&lt; cost &lt;&lt; endl;
  return 0;
}</pre>
</div></div>



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

<pre class="crayon-plain-tag"># Author: Huahua
from collections import defaultdict
from heapq import *

n = 4
edges = [[0,1,1],[0,3,3],[0,2,6],[2,3,2],[1,2,4],[1,3,5]]
g = defaultdict(list)
for e in edges:
  g[e[0]].append((e[1], e[2]))
  g[e[1]].append((e[0], e[2]))

q = []
cost = 0
seen = set()
heappush(q, (0, 0))
for _ in range(n):
  while True:
    w, u = heappop(q)
    if u in seen: continue  
    cost += w
    seen.add(u)
    for v, w in g[u]:
      if v in seen: continue
      heappush(q, (w, v))
    break

print(cost)</pre>
</div></div>



<h2><strong>Kruskal&#8217;s Algorithm</strong></h2>



<p>Time complexity: O(ElogV)<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
#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;vector&gt;
#include &lt;functional&gt;
#include &lt;numeric&gt;
using namespace std;

int main(int argc, char** argv) {
  const int n = 4;
  vector&lt;vector&lt;int&gt;&gt; edges{{0,1,1},{0,3,3},{0,2,6},{2,3,2},{1,2,4},{1,3,5}};    
  vector&lt;vector&lt;int&gt;&gt; q; // (w, u, v)  
  for (const auto&amp; e : edges)    
    q.push_back({e[2], e[0], e[1]});
  sort(begin(q), end(q));

  vector&lt;int&gt; p(n);
  iota(begin(p), end(p), 0);

  function&lt;int(int)&gt; find = [&amp;](int x) {
    return x == p[x] ? x : p[x] = find(p[p[x]]);
  };

  int cost = 0;
  for (const auto&amp; t : q) {    
    int w = t[0], u = t[1], v = t[2];      
    int ru = find(u), rv = find(v);      
    if (ru == rv) continue;
    p[ru] = rv; // merge (u, v)      
    cost += w;
  }  
  cout &lt;&lt; cost &lt;&lt; endl;

  return 0;
}</pre>
</div></div>



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

<pre class="crayon-plain-tag">from collections import defaultdict
from heapq import *

n = 4
edges = [[0,1,1],[0,3,3],[0,2,6],[2,3,2],[1,2,4],[1,3,5]]
p = list(range(n))


def find(x):
  if x != p[x]: p[x] = find(p[p[x]])
  return p[x]

cost = 0
for u, v, w in sorted(edges, key=lambda x: x[2]):
  ru, rv = find(u), find(v)
  if ru == rv: continue
  p[ru] = rv
  cost += w

print(cost)</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/sp/minimum-spanning-tree-sp18/">花花酱 Minimum Spanning Tree (MST) 最小生成树 SP18</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/sp/minimum-spanning-tree-sp18/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
