题目链接:https://www.nowcoder.com/acm/contest/133/A
题目描述
现在有一棵被Samsara-Karma染了k种颜色的树,每种颜色有着不同的价值
Applese觉得Samsara-Karma染的太难看了,于是打算把整棵树重新染成同一种颜色
但是,由于一些奥妙重重的原因,每一次染色Applese可以选择两个有边相连的点,将其中一个染成另一个的颜色。而进行一次这样的操作需要付出两种颜色价值和的代价
现在,Applese的钱要用来买书(game),所以他想要最小化代价
输入描述:
输入包括若干行 第一行包括一个数n,表示这棵树有n个节点 第二行包括n个数,第i个数表示第i个节点的颜色coli **注意:一个颜色的标号即价值
接下来的n - 1行,每行包括两个数u, v,表示u节点与v节点之间有一条无向边
n ≤ 100000, 1 ≤ coli ≤ 1e9,数据保证是一棵树
输出描述:
输出包括一行 第一行包括一个数,表示最小代价
示例1
输入
4 2 3 4 3 1 2 2 3 3 4
输出
12
分析:因为每一个点都要变成同一种颜色,所以要枚举每一种颜色的情况,比如都变成2 ,因为其余不是2的数都要变成2,所以就统计要变成2的个数,这个样例有3个要变成2,所以要加6,同时,他们要变成2,根据题意也要加上他自身,所以3+4+3,然后加上6;就这样计算变每一种颜色要耗费多少代价,从中选出最小值。
下面是代码:
#include<cstdio>
#include<map>
#include<iostream>
#include<algorithm>
typedef
long
long
ll;
const
int
maxn=100100;
using
namespace
std;
map<ll,
int
>cnt;
int
main(){
int
n;
ll a[maxn];
ll sum=0;
scanf
(
"%d"
,&n);
for
(
int
i=0;i<n;i++){
scanf
(
"%lld"
,&a[i]);
sum+=a[i];
cnt[a[i]]++;
}
ll flag=sum;
int
t=n-1;
int
u,v;
while
(t--){
scanf
(
"%d %d"
,&u,&v);
}
ll ans;
sum=flag;
sum=sum-(ll)a[0]*cnt[a[0]]+(ll)(n-cnt[a[0]])*a[0];
ans=sum;
for
(
int
i=1;i<n;i++){
sum=flag;
sum=sum-(ll)a[i]*cnt[a[i]]+(ll)(n-cnt[a[i]])*a[i];
ans=min(ans,sum);
}
printf
(
"%lld\n"
,ans);
}