zoukankan      html  css  js  c++  java
  • Gym

    给你一棵树 你可以取K条链 一条链为根到叶子的路径 问你K条链最多覆盖树上多少个节点

    贪心的做 肯定是每次取最长链 但是取完最长链 一颗树就会变为若干个森林 我们要维护当前所有森林里的最长链

    ans数组记录当前节点子树里的最长链长为多少 dfs到一个节点 就把除了最长链上的儿子的ans全部push到q里(这里可以维护一个最大值来优化掉优先队列qq)

    然后最后把ans[1] push到q里 取最大的k个即可

    为什么这么做是正确的 因为优先队列q里存的是每个节点的父亲节点去掉最长链后自己当根节点时子树的最长链长度

    我们每次贪心就是从若干个森林里取出最长链最长的哪条消掉 所以直接取q的前k个即可

    #include<bits/stdc++.h>
    using namespace std;
    vector<int> g[100005];
    int ans[100005];
    priority_queue<int> q;
    void dfs(int x) {
            priority_queue<int> qq;
            ans[x] = 1;
            for (int v : g[x]) {
                    dfs(v);
                    qq.push(ans[v]);
            }
            if (g[x].size()) {
                    ans[x] = qq.top() + 1;
                    qq.pop();
                    while (qq.size()) {
                            q.push(qq.top());
                            qq.pop();
                    }
            }
    }
    int main() {
            int n, k, x;
            scanf("%d %d", &n, &k);
            for (int i = 2; i <= n; i++) {
                    scanf("%d", &x);
                    g[x].push_back(i);
            }
            int anser = 0;
            dfs(1);
            q.push(ans[1]);
            while (k--&&q.size()) {
                    anser += q.top();
                    q.pop();
            }
            printf("%d
    ", anser);
    }
  • 相关阅读:
    POJ3297+map字符串处理
    POJ3204+DInic+maxflow
    HDU4704+费马小定理
    FZU-1924+判断环/DFS/BFS
    FZU-1921+线段树
    FZU-1926+KMP
    CodeForce 339:A+B+C
    HDU2896+AC自动机
    POJ2527+多项式除法
    鼠标移入移出事件
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11754534.html
Copyright © 2011-2022 走看看