zoukankan      html  css  js  c++  java
  • 题解【Codeforces1336A】Linova and Kingdom

    题面

    一开始的想法肯定就是按照深度来贪心,选深度最深的 (k) 个点,然后发现这样做其实是错误的。

    我们发现在此题中,选一个点之前肯定已经把它的所有子树中的节点全部选完了,否则先选择它的子树中的节点答案肯定更优。

    然后我们考虑计算出一个节点的贡献:

    • 选择了当前节点之后,当前节点 (i) 的幸福值为 (dep_i - 1)(dep_1 = 1))。
    • 但是 (i) 的所有子树中的节点答案都会减少 (1),因此答案还会减少 (sz_i - 1)
    • 因此节点 (i) 对答案的贡献就是 (dep_i - 1 - (sz_i - 1) = dep_i - sz_i)

    那么我们按照 (dep_i - sz_i) 从大到小排序,然后选前 (k) 大的加起来就是答案。

    注意开 ( ext{long long})

    #include <bits/stdc++.h>
    #define DEBUG fprintf(stderr, "Passing [%s] line %d
    ", __FUNCTION__, __LINE__)
    #define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
    
    using namespace std;
    
    typedef long long LL;
    typedef pair <int, int> PII;
    typedef pair <int, PII> PIII;
    
    inline int gi()
    {
    	int f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return f * x;
    }
    
    inline LL gl()
    {
    	LL f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return f * x;
    }
    
    const int INF = 0x3f3f3f3f, N = 200003, M = N << 1;
    
    int n, k;
    int tot, head[N], ver[M], nxt[M];
    int dep[N], sz[N], ans[N];
    
    inline void add(int u, int v)
    {
        ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
    }
    
    void dfs(int u, int f)
    {
        dep[u] = dep[f] + 1, sz[u] = 1;
        for (int i = head[u]; i; i = nxt[i])
        {
            int v = ver[i];
            if (v == f) continue;
            dfs(v, u);
            sz[u] += sz[v];
        }
        ans[u] = dep[u] - sz[u];
    }
    
    int main()
    {
    	//File("");
        n = gi(), k = gi();
        for (int i = 1; i < n; i+=1) 
        {
            int u = gi(), v = gi();
            add(u, v), add(v, u);
        }
        dfs(1, 0);
        sort(ans + 1, ans + 1 + n); reverse(ans + 1, ans + 1 + n);
        LL sum = 0;
        for (int i = 1; i <= k; i+=1) sum += ans[i];
        cout << sum << endl;
    	return 0;
    }
    
  • 相关阅读:
    Vue路由机制
    谷歌浏览器打不开应用商店的解决方法
    Vue报错——Component template should contain exactly one root element. If you are using vif on multiple elements, use velseif to chain them instead.
    Vue.js学习之——安装
    Vue使用axios无法读取data的解决办法
    关于localstorage存储JSON对象的问题
    2013年整体计划
    个人喜欢的警语收集
    Linux防火墙的关闭和开启
    Flex修改title 转载
  • 原文地址:https://www.cnblogs.com/xsl19/p/12740875.html
Copyright © 2011-2022 走看看