版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SSL_hzb/article/details/85393851
题意
有
个村,它们需要联网,联网的方式有两种:
1、直接联网,花费
元
2、与另一个村连起来,花费
它们之间的曼哈顿距离,如果另一个村有网,那么这个村也会有网。
求最小花费。
思路
直接做最小生成树,特别要注意的是,如果两村连起来的花费超过 元我们就不连,因为直接联网会比这样更优,最后给每个联通块加上 ,表示每个块都有一个村有网共享给它们。
代码
#include<cmath>
#include<cstdio>
#include<algorithm>
struct node{
int x, y, v;
}e[1000001];
int x[1001], y[1001], fa[1001];
int ans;
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int cmp(node x, node y) {
return x.v < y.v;
}
int main() {
int n, a, b, cnt = 0;
scanf("%d %d %d", &n, &a, &b);
for (int i = 1; i <= n; i++)
scanf("%d %d", &x[i], &y[i]);
for (int i = 1; i < n; i++)
for (int j = i + 1; j <= n; j++)
e[++cnt] = (node){i, j, abs(x[i] - x[j]) + abs(y[i] - y[j])};
for (int i = 1; i <= n; i++)
fa[i] = i;
std::sort(e + 1, e + cnt + 1, cmp);
for (int i = 1; i <= n; i++) {
int f1 = find(e[i].x), f2 = find(e[i].y);
if (f1 == f2) continue;
if (e[i].v * b <= a) {
fa[f1] = f2;
ans += e[i].v * b;
}
}
for (int i = 1; i <= n; i++)
if (fa[i] == i) ans += a;
printf("%d", ans);
}