这道题就是最小生成树板子题:
求连接所有田地且所需管道长度最短的方案。其中每个田地都是一个节点,每个管道都是一条边,每条管道的距离就是边权。这道题就转化为了求连接所有点的边权累加和最小的方案。
可以用kurskal和prim算法,但是kurskal更好记,就用kurskal了。
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
int p[N];
struct NODE {
double x, y, z;
};
bool cmp(NODE t1, NODE t2) {
return t1.z < t2.z;
}
vector<NODE>grap;
int find(int x) {
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void uni(int a, int b) {
a = find(a), b = find(b);
p[a] = b;
}
int main() {
int n;
cin >> n;
for (int i = 0; i <= 80; i++)
p[i] = i;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int x;
cin >> x;
if (i == j)
continue;
grap.push_back({i, j, x});
}
}
sort(grap.begin(), grap.end(), cmp);
int ans = 0;
for (int i = 0; i < grap.size(); i++) {
int x = grap[i].x, y = grap[i].y, z = grap[i].z;
if (find(x) != find(y))
uni(x, y), ans += z;
}
cout << ans << endl;
return 0;
}