描述
一个有 n 户人家的村庄,有 m 条路相互连接着。村里现在要修路,每条路都有一个成本价格,现在请你帮忙计算下,最少需要花费多少钱,就能让这 n 户人家连接起来。cost 为一个二维数组,每个元素是一个长度为 3 的一维数组 a , a[0] 和 a[1] 表示村庄 a[0] 和村庄 a[1] 有一条路,修这条路的成本价格为 a[2] 。
每户之间可能有多条道路连接,但不可能自己与自己相连。
进阶: 时间复杂度 𝑂(𝑛+𝑚𝑙𝑜𝑔𝑚)O(n+mlogm) , 空间复杂度 𝑂(𝑛)O(n)
示例1
输入:
3,3,[[1,3,3],[1,2,1],[2,3,1]]
返回值:
2
#include <unordered_set>
#include <vector>class Solution {
public:static bool compare(std::vector<int>& e1, std::vector<int>& e2){return e1[2] < e2[2]; //比较两条边的权重}/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 返回最小的花费代价使得这n户人家连接起来* @param n int整型 n户人家的村庄* @param m int整型 m条路* @param cost int整型vector<vector<>> 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价* @return int整型*/int miniSpanningTree(int n, int m, vector<vector<int> >& cost) {// write code herestd::unordered_set<int> points; //村庄集合,即图中的顶点集合std::sort(cost.begin(), cost.end(), compare); //cost数组表示图中边的集合,按边的权重从小大到达排序int res = cost[0][2]; //取出最小权重的边, 初始化返回值points.insert(cost[0][0]); //将该边的端点插入顶点集合中points.insert(cost[0][1]); //将该边的端点插入顶点集合中while(true){if(points.size() == n) //如果n个村庄都已在集合中,说明最小生成树已生成break;for(auto it = cost.begin(); it != cost.end(); it++) //按权重从小到大遍历每个边,依次取出权重最小的边:iter{auto& edge = *it;//如果该边的两个端点有一个不在顶点集合points中,则加入if((points.find(edge[0]) == points.end() || points.find(edge[1]) == points.end()) && (points.find(edge[0]) != points.end() || points.find(edge[1]) != points.end())){res += edge[2]; //权重累加points.insert(edge[0]); //将点加到集合中,unordered_set 自动去重points.insert(edge[1]); //将点加到集合中, unordered_set 自动去重cost.erase(it); //删除边break; } }}return res;}
};