文章目錄
1. 題目
想象一下你是個城市基建規劃者,地圖上有 N 座城市,它們按以 1 到 N 的次序編號。
給你一些可連接的選項 conections,其中每個選項 conections[i] = [city1, city2, cost] 表示將城市 city1 和城市 city2 連接所要的成本。(連接是雙向的,也就是說城市 city1 和城市 city2 相連也同樣意味著城市 city2 和城市 city1 相連)。
返回使得每對城市間都存在將它們連接在一起的連通路徑(可能長度為 1 的)最小成本。
該最小成本應該是所用全部連接代價的綜合。如果根據已知條件無法完成該項任務,則請你返回 -1。
示例 1:
輸入:N
= 3, conections
= [[1,2,5],[1,3,6],[2,3,1]]
輸出:
6
解釋:
選出任意
2 條邊都可以連接所有城市,我們從中選取成本最小的
2 條。
示例 2:
輸入:N
= 4, conections
= [[1,2,3],[3,4,4]]
輸出:
-1
解釋:
即使連通所有的邊,也無法連接所有城市。提示:
1 <= N
<= 10000
1 <= conections
.length
<= 10000
1 <= conections
[i
][0], conections
[i
][1] <= N
0 <= conections
[i
][2] <= 10^5
conections
[i
][0] != conections
[i
][1]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/connecting-cities-with-minimum-cost
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
2. 解題
圖Graph–最小生成樹
1. Kruskal
- 將邊的權值排序,小的先遍歷,用并查集檢查兩個頂點是否合并了,沒有合并則將該邊加入生成樹
- 也可以使用優先隊列實現(相當于排序)
class dsu
{vector
<int> f
;
public:dsu(int n
){f
.resize(n
);for(int i
= 0; i
< n
; ++i
)f
[i
] = i
;}void merge(int a
, int b
){int fa
= find(a
);int fb
= find(b
);f
[fa
] = fb
;}int find(int a
){int origin
= a
;while(a
!= f
[a
]){a
= f
[a
];}return f
[origin
] = f
[a
];}
};class Solution {
public:int minimumCost(int N
, vector
<vector
<int>>& connections
) {dsu
u(N
+1);sort(connections
.begin(), connections
.end(),[&](auto a
, auto b
){return a
[2] < b
[2];});int edge
= 0, p1
, p2
, dis
, total
= 0;for(int i
= 0; i
< connections
.size(); ++i
){p1
= connections
[i
][0];p2
= connections
[i
][1];dis
= connections
[i
][2];if(u
.find(p1
) != u
.find(p2
)){u
.merge(p1
,p2
);edge
++;total
+= dis
;}if(edge
== N
-1)break;}return edge
==N
-1 ? total
: -1;}
};
1504 ms 158.6 MB
2. prim
- 把一個初始頂點的所有邊加入優先隊列
- 取出最短的邊,把這條邊的另一個頂點相關的邊加入隊列
- 再取出最小的邊,重復下去,直到所有頂點加入過了
struct cmp
{bool operator()(const pair
<int,int>& a
, const pair
<int,int>& b
) const{return a
.second
> b
.second
;}
};
class Solution {
public:int minimumCost(int N
, vector
<vector
<int>>& connections
) {vector
<bool> vis(N
+1, false);vector
<vector
<pair
<int,int>>> edges(N
+1,vector
<pair
<int,int>>());for(auto& c
: connections
){edges
[c
[0]].push_back({c
[1],c
[2]});edges
[c
[1]].push_back({c
[0],c
[2]});}priority_queue
<pair
<int,int>, vector
<pair
<int,int>>, cmp
> q
;int to
, distance
, total
= 0, edge
= 0;vis
[1] = true;for(auto& e
: edges
[1])q
.push(e
); while(!q
.empty()){to
= q
.top().first
;distance
= q
.top().second
;q
.pop();if(!vis
[to
]){vis
[to
] = true;total
+= distance
;edge
++;if(edge
== N
-1)return total
;for(auto& e
: edges
[to
])q
.push(e
); }}return -1;}
};
492 ms 40.9 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!
總結
以上是生活随笔為你收集整理的LeetCode 1135. 最低成本联通所有城市(最小生成树+排序+并查集)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。