【CF1466D】13th Labour of Heracles 出度统计 + 贪心

CF good bye2020 —D

链接


传送门

分析

昨天(今天)coderforces good bye2020上面的题目,起初的想法是dfs,结果直接超时,后来又模拟了一下过程,发现是出度统计。即一个节点最多被使用的次数等于它的出度(即与他相连的节点个数),在可以选择的节点中,优先选择权值最大的节点。我们把w[i]的和先求出来,得到sum,相当于每个节点都用了一次,然后在通过出度将剩下可以使用的节点记录下来,排序一下即可。实际上就是找规律,简单贪心一下。

code

#include <algorithm>
#include <cstring>
#include <cctype>

inline int read(){
    
    
    int x = 0; char ch = getchar();
    while (!isdigit(ch)){
    
    ch = getchar();}
    while (isdigit(ch)){
    
    x = (x<<1)+(x<<3)+(ch^48); ch = getchar();}
    return x;
}

inline void write(long long x){
    
    
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

const int N = 1e5 + 10;
int t, n, cnt;
int w[N], val[N];
int out[N];

void solve(){
    
    
    long long res = 0;
    n = read(), cnt = 0;
    memset(out, 0, sizeof out);
    memset(val, 0, sizeof val);
    for (int i = 1; i <= n; ++i) res += w[i] = read();

    for (int i = 1, x, y; i < n; ++i) {
    
    
        x = read(), y = read();
        ++out[x]; ++out[y];
    }

    for (int i = 1; i <= n; ++i)
        for (int j = 1; j < out[i]; ++j)
            val[++cnt] = w[i];
    std::sort(val + 1, val + 1 + cnt);

    for (int i = cnt + 1; i >= 1; i--) {
    
    
        res += val[i];
        write(res), putchar(' ');
    }
    putchar('\n');
}

int main() {
    
    
    t = read();
    while (t--)
        solve();
    return 0;
}

不知不觉2020也快要过去啦。

猜你喜欢

转载自blog.csdn.net/weixin_50070650/article/details/112004522
今日推荐