一个有 n 户人家的村庄,有 m 条路相互连接着。村里现在要修路,每条路都有一个成本价格,现在请你帮忙计算下,最少需要花费多少钱,就能让这 n 户人家连接起来。为一个二维数组,每个元素是一个长度为 3 的一维数组 , 和 表示村庄 和村庄 有一条路,修这条路的成本价格为 。每户之间可能有多条道路连接,但不可能自己与自己相连。具体实现一下用C++
时间: 2023-12-03 22:42:59 浏览: 282
用C++做了个计算器,有兴趣研究下吧
这是一个经典的最小生成树问题,可以使用 Kruskal 算法求解。Kruskal 算法的基本思路是将所有的边按照权值从小到大排序,然后依次加入最小生成树中,直到所有节点都被连接上。
具体实现步骤如下:
1. 将所有边按照权值从小到大排序。
2. 依次遍历每一条边,判断该边的两个端点是否在同一个集合中,如果不在,则将它们合并,并将该边加入最小生成树中。
3. 直到所有节点都被连接上,算法结束。
代码实现如下:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
int n, m;
int fa[MAXN];
struct Edge {
int u, v, w;
bool operator<(const Edge& other) const {
return w < other.w;
}
};
vector<Edge> edges;
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void merge(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) fa[fx] = fy;
}
int kruskal() {
int ans = 0, cnt = 0;
sort(edges.begin(), edges.end());
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 0; i < edges.size(); i++) {
int u = edges[i].u, v = edges[i].v, w = edges[i].w;
if (find(u) != find(v)) {
merge(u, v);
ans += w;
cnt++;
if (cnt == n - 1) break;
}
}
return ans;
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
edges.push_back({u, v, w});
}
cout << kruskal() << endl;
return 0;
}
```
其中,`Edge` 结构体表示一条边,`operator<` 用于排序,`find` 函数和 `merge` 函数分别用于查找祖先和合并两个节点所在的集合。最后调用 `kruskal` 函数即可得到最小生成树的权值和。
阅读全文