克鲁斯卡尔算法
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int par[1001], v[1001], adp[1001];
struct node {
int from, to, cost;
} nds[1000000];
bool cmp(node n1, node n2) {
return n1.cost < n2.cost;
}
int fd(int id) {
return (par[id] != id) ? par[id] = fd(par[id]) : par[id];
}
void inti(int n) {
for (int i = 1; i <= n; i++) {
par[i] = i;
v[i] = 1;
}
}
int main() {
int t, n, i, j, p, idx, coun, a, b, ans;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (i = 1; i <= n; i++) {
scanf("%d", &adp[i]);
}
idx = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
scanf("%d", &p);
if (i == j)continue;
nds[idx].from = i;
nds[idx].to = j;
nds[idx].cost = adp[i] + adp[j] + p;
idx++;
}
}
sort(nds, nds + idx, cmp);
coun = 0;
ans = 0;
inti(n);
for (i = 0; i < idx; i++) {
a = fd(nds[i].from);
b = fd(nds[i].to);
if (a != b) {
if (v[a] < v[b]) {
v[b] += v[a];
par[a] = b;
} else {
v[a] += v[b];
par[b] = a;
}
ans += nds[i].cost;
if (++coun == n - 1)break;
}
}
printf("%d\n", ans);
}
}