算是最小生成树的模板题吧
最小生成树算法有 prim 和 kruskal 两个
我一般会用kruskal,好理解,代码好写
kruskal会用到并差集,很经典的算法
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int f[105];//记录父亲节点
int r[105];//记录深度
struct node {//村庄编号和距离
int a;
int b;
int val;
}s[10005];
bool cmp(node a, node b) {/*排序依据*/
return a.val < b.val;
}
void init() {/*初始化*/
for (int i = 0; i < 105; i++) f[i] = i;
memset(r, 0, sizeof(r));
}
int fin(int x) {//寻找x节点的父亲节点
return x == f[x] ? x : fin(f[x]);
}
void merge(int a, int b) {//连接a b节点
int fa = fin(a);
int fb = fin(b);
if (r[fa] < r[fb]) f[fa] = fb;
else {
f[fb] = fa;
if (r[fa] == r[fb]) r[fa]++;
}
}
bool same(int a, int b) {//判断a b节点是否一样
return fin(a) == fin(b);
}
int main() {
ios::sync_with_stdio(false);//关闭什么什么东西,让cin更快一点
//freopen("in.txt", "r", stdin);
int n;
while (cin >> n && n) {
init();
int m = n * (n - 1) / 2;
for (int i = 0; i < m; i++) {
cin >> s[i].a >> s[i].b >> s[i].val;
}
sort(s, s + m, cmp);
int ans = 0;
for (int i = 0; i < m; i++) {
if (!same(s[i].a, s[i].b)) {
merge(s[i].a, s[i].b);
ans += s[i].val;
}
}
cout << ans << endl;
}
return 0;
}