一、内容
题意:给定一棵树,求染完所有节点的最少代价。
二、思路
三、代码
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e3 + 5;
struct Node{
int size, sum, fa;
double avg;
} nodes[N];
int n, root, a, b;
int find() {
int v = 0;
double mavg = -1;
//查找出最大的avg
for (int i = 1; i <= n; i++) {
if (i != root && mavg < nodes[i].avg) {
v = i;
mavg = nodes[i].avg;
}
}
return v;
}
int main() {
while (scanf("%d%d", &n, &root), n) {
int ans = 0;
for (int i = 1; i <= n; i++) {
Node &t = nodes[i];
scanf("%d", &t.sum);
t.size = 1;
t.avg = t.sum;
//加上每个节点原始的一次
ans += t.sum;
}
for (int i = 1; i < n; i++) {
scanf("%d%d", &a, &b);
nodes[b].fa = a;
}
//每次找节点中等效权值avg最大的
for (int k = 1; k < n; k++) {
int v = find();
//加上父亲的层次
int fa = nodes[v].fa;
ans += nodes[v].sum * nodes[fa].size;
//进行合并
nodes[fa].sum += nodes[v].sum;
nodes[fa].size += nodes[v].size;
nodes[fa].avg = (double)nodes[fa].sum / nodes[fa].size;
for (int i = 1; i <= n; i++) {
if (nodes[i].fa == v) {
nodes[i].fa = fa;
}
}
nodes[v].avg = -1;//等于删除操作
}
printf("%d\n", ans);
}
return 0;
}