Kruskal,最小生成树
参考:https://blog.csdn.net/shanwenkang/article/details/81021247
//Kruskal
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 80;
struct Edge {//保存边
char from, to;
int cost;
};
Edge edge[maxn];
char father[200];
int n;//村庄个数
int num;//道路总数
int ans;//结果
bool cmp(Edge a, Edge b) {//按代价从小到大排序
return a.cost < b.cost;
}
void init() {//初始化
char tmp;
for (int i = 0; i < n; i++) {
tmp = i + 'A';
father[tmp] = tmp;
}
}
char Find(char x) {//找祖先结点
while (x != father[x])
x = father[x];
return x;
}
void Union(char x, char y) {//并查集,合并
x = Find(x), y = Find(y);
if (x != y)
father[y] = x;
}
void Kruskal() {
int a=0;//计算顶点数
char x, y;
for (int i = 0; i < num; i++) {
x = edge[i].from, y = edge[i].to;
if (Find(x) == Find(y))
continue;
else {
Union(x, y);
ans += edge[i].cost;
a++;
if (a == n - 1) //所有村庄都已加入
break;
}
}
}
int main() {
int cost,k;
char from, to;
while (cin >> n && n) {
num = 0,ans=0;
init();
n--;
while (n--) {
cin >> from >> k;
while (k--) {
cin >> to >> cost;
edge[num].from = from;//每条边
edge[num].to = to;
edge[num++].cost = cost;
}
}
sort(edge, edge + num, cmp);//排序
Kruskal();
cout << ans << endl;
}
return 0;
}