【题目】园区里面有很多大楼,编号从 1~N。第 i 大楼可以自己花钱买路由器上网,费用为 cost[i-1],也可以从别的大楼拉一根网线来上网,比如大楼 a 和大楼 b 之间拉网线的费用为 c,表示为一条边 [a, b, c]。输入为每个大楼自己买路由器和拉网线的费用,请问,让所有大楼都能够上网的最小费用是多少?上网具有联通性,只要与能够上网的大楼连通,即可上网。
输入:cost = [1, 2, 3], edges = [[1,2,100], [2,3,3]]
输出:6
class UF {
public:
vector<int>F;
int totoalCost = 0;
vector<int> Cnt;
UF(int n){
F.resize(n);
for (int i =0; i < n; i++) {
F[i] = i;
}
totoalCost = 0;
}
int Find(int x) {
return x == F[x] ? x : F[x] = Find(F[x]);
}
void Union(int x, int y, int cost){
int xpar = Find(x);
int ypar = Find(y);
if (xpar != ypar) {
F[xpar] = ypar;
totoalCost += cost;
}
}
};
class Solution4 {
// N 表示结点数目
// cost[i-1]表示结点i自己买路由器的代价
// es[x] = [a, b, c]表示大楼a,b之间拉网线的费用
// 输出所有大楼通网的最小费用
public:
int minCostToSupplyWater(int N, vector<int> &cost, vector<vector<int>> &es){
UF uf(N +1);
// 每个结点都要自己挖水,那么我们可以认为这样
// 0号楼已经有网络了,可以用0费用上网
// i号楼与0号楼拉网线,需要的费用是cost[i-1]
// 那么这里就多了N条边
for (int i =0; i <=N; i++) {
vector<int>tmp {0,i,cost[i-1]};
es.push_back(tmp);
}
sort(es.begin(), es.end(), [](const vector<int>&a, const vector<int> &b){
return a[2] < b[2];
});
for (auto &e : es) {
uf.Union(e[0], e[1], e[2]);
}
return uf.totoalCost;;
}
};