题意
将一个图分成若干集合,总代价为使用的边权和每个集合中的最小点权。最小化代价。
思路
新建一个点,将所有点连向它,边权为这个点的点权。之后就是最小生成树了。
代码
#include<cstdio>
#include<algorithm>
struct node {
int u, v, w;
}edge[500501];
int n, tot;
int fa[1001];
long long ans;
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int cmp(node x, node y) {
return x.w < y.w;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1, x; j <= n; j++) {
scanf("%d", &x);
if (j > i) {
edge[++tot].u = i;
edge[tot].v = j;
edge[tot].w = x;
}
}
for (int i = 1; i <= n; i++) {
fa[i] = i;
scanf("%d", &edge[++tot].w);
edge[tot].u = 0;
edge[tot].v = i;
}
std::sort(edge + 1, edge + tot + 1, cmp);
for (int i = 1; i <= tot; i++) {
int f1 = find(edge[i].u), f2 = find(edge[i].v);
if (f1 == f2) continue;
fa[f1] = f2;
ans += edge[i].w;
}
printf("%lld", ans);
}