牛客网 Wannafly 挑战赛20 A 染色

题目链接: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);

     

}

猜你喜欢

转载自blog.csdn.net/qq_37774171/article/details/81140975