kruskal 配并差集
模板题
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int mx = 105;
//存储节点上级
int f[mx];
//存储两节点之间的距离
struct node {
int a, b;
double val;
};
//计算两个节点之间的距离
double length(double a[], double b[]) {
return sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
}
//排序op
bool cmp(node a, node b) {
return a.val < b.val;
}
//初始化数组,设置每个节点的上级是自己
void init() {
for (int i = 0; i < mx; i++) f[i] = i;
}
//寻找x节点的最上级
int fin(int x) {
return f[x] = x == f[x] ? x : fin(f[x]);
}
//将x节点和y节点连接起来
void merge(int x, int y) {
f[fin(x)] = fin(y);
}
//判断x节点和y节点是否已经连接
bool same(int x, int y) {
return fin(x) == fin(y);
}
int main() {
//freopen("in.txt", "r", stdin);
int n;
while (cin >> n) {
//初始化
init();
int cnt = 0;
node len[mx * mx];
//输入每个节点与其他节点的距离
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
len[cnt].a = i;
len[cnt].b = j;
cin >> len[cnt++].val;
}
}
int Q; cin >> Q;
//输入本来就连接的节点,直接连接,不用计算距离
while (Q--) {
int a, b; cin >> a >> b;
if (!same(a, b)) merge(a, b);
}
//按照距离从小到大排序
sort(len, len + cnt, cmp);
double sum = 0;
for (int i = 0; i < cnt; i++) {
if (!same(len[i].a, len[i].b)) {
//将符合条件的两个节点连接起来
merge(len[i].a, len[i].b);
sum += len[i].val;
}
}
cout << sum << endl;
}
}