• 树形dp+贪心+增量法+排序——cf1241E(好题)


    /*
    给定一棵树,每个结点最多选和其相连的k条边,问使边权和最大的策略 
    
    dp[u][0|1]用来表示u没连父边|连了父边 时u子树下的最优解
    如果u不和任意一个儿子连边,那么u下的收益是tot=sum{dp[v][0]}
    现在我们在其中选择一个儿子v连到u,那么 tot的增量就是 dv=dp[v][1]-dp[v][0] + w;
    
    求dp[u][0]时,我们最多可以选择k个儿子相连,那么就把 所有dv进行排序,然后找前面k个大于0的即可
    dp[u][1]同理,但是只要选择k-1个儿子即可 
    */
    #include<bits/stdc++.h>
    #include<vector>
    using namespace std;
    #define N 500005
    #define ll long long 
     
    vector<pair<ll,ll> >G[N];
    int n,k;
    ll dp[N][2];
    
    int cmp(ll a,ll b){
        return a>b;
    }
    
    void dfs(int u,int pre){
        ll tot=0;
        vector<ll>d;d.clear();
        for(auto p:G[u]){
            int v=p.first;
            if(v==pre)continue;
            dfs(v,u);
            d.push_back(dp[v][1]-dp[v][0]+p.second);
            tot+=dp[v][0];
        }
        sort(d.begin(),d.end(),cmp);
        //求出dp[u][0] 
        dp[u][0]=tot;
        for(int i=0;i<min(k,(int)d.size());i++)
            if(d[i]>0)dp[u][0]+=d[i];
        //求出dp[u][1] 
        dp[u][1]=tot;
        for(int i=0;i<min(k-1,(int)d.size());i++)
            if(d[i]>0)dp[u][1]+=d[i];
        
    }
                 
    void init(){
        for(int i=1;i<=n;i++)G[i].clear();
        for(int i=1;i<=n;i++)dp[i][0]=dp[i][1]=0;
    }
                 
    int main(){
        int q;cin>>q;
        while(q--){
            init();
            cin>>n>>k; 
            for(int i=1;i<n;i++){
                int u,v,w;scanf("%d%d%d",&u,&v,&w);
                G[u].push_back(make_pair(v,w));
                G[v].push_back(make_pair(u,w)); 
            }
            
            /*for(int i=1;i<=n;i++){
                for(auto v:G[i])
                    cout<<v.first<<" ";
                puts("");
            }*/
            
            dfs(1,0);
            
            cout<<dp[1][0]<<'
    ';
        }
    }
  • 相关阅读:
    如何给发票抬头增加页签
    记录激活SAP SMTP服务过程
    反射
    乱码问题
    使用idea的常用的技巧
    解决double的值相加的问题
    代理模式之静态代理
    foreach的真面目
    记录java的面试的每一个瞬间
    变量的经典
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11700111.html
Copyright © 2020-2023  润新知