zoukankan      html  css  js  c++  java
  • BZOJ3252攻略——长链剖分+贪心

    题目描述

    题目简述:树版[k取方格数]
    众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏。今天他得到了一款新游戏《XX
    半岛》,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景。所有场景和选择支构成树状
    结构:开始游戏时在根节点(共通线),叶子节点为结局。每个场景有一个价值,现在桂马开启攻略之神模式,同
    时攻略k次该游戏,问他观赏到的场景的价值和最大是多少(同一场景观看多次是不能重复得到价值的)
    “为什么你还没玩就知道每个场景的价值呢?”
    “我已经看到结局了。”

    输入

    第一行两个正整数n,k
    第二行n个正整数,表示每个场景的价值
    以下n-1行,每行2个整数a,b,表示a场景有个选择支通向b场景(即a是b的父亲)
    保证场景1为根节点
    n<=200000,1<=场景价值<=2^31-1

    输出

    输出一个整数表示答案

    样例输入

    5 2
    4 3 2 1 1
    1 2
    1 5
    2 3
    2 4

    样例输出

    10
     
      因为重复选同一个点不计入答案多次,也就相当于选k条链(互不相交),使每条链长尽可能大。每个节点的深度就是从这个点到根路径上的点权和,而每条链的长度则是链上所有点的点权和。那么我们就可以对整棵树进行长链剖分,然后记录每条长链的长度,取前k大条链就好了。如果不了解长链剖分可以参见->长链剖分
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int n,k;
    int q[200010];
    int cnt;
    int tot;
    int head[200010];
    int next[400010];
    int to[400010];
    int x,y;
    int v[200010];
    int son[200010];
    ll d[200010];
    int f[200010];
    ll mx[200010];
    ll val[200010];
    ll ans;
    void add(int x,int y)
    {
        tot++;
        next[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
    }
    bool cmp(int x,int y)
    {
        return val[x]>val[y];
    }
    void dfs(int x,int fa)
    {
        d[x]=d[fa]+v[x];
        f[x]=fa;
        mx[x]=d[x];
        for(int i=head[x];i;i=next[i])
        {
            if(to[i]!=f[x])
            {
                dfs(to[i],x);
                mx[x]=max(mx[x],mx[to[i]]);
                if(mx[to[i]]>mx[son[x]])
                {
                    son[x]=to[i];
                }
            }
        }
    }
    void dfs2(int x,int tp)
    {
        val[tp]+=v[x];
        if(son[x])
        {
            dfs2(son[x],tp);
        }
        for(int i=head[x];i;i=next[i])
        {
            if(to[i]!=son[x]&&to[i]!=f[x])
            {
                q[++cnt]=to[i];
                dfs2(to[i],to[i]);
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&v[i]);
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        q[++cnt]=1;
        dfs2(1,1);
        sort(q+1,q+1+cnt,cmp);
        for(int i=1;i<=k;i++)
        {
            ans+=val[q[i]];
        }
        printf("%lld",ans);
    }
  • 相关阅读:
    转!!javaMail使用网易163邮箱报535 Error: authentication failed
    银行卡验证(验证是否存在,卡号类型,归属行)
    Navicat已经成功连接,密码忘记的解决方法
    Inline&IAT Hook原理
    x64dbg尝鲜
    C# 通过Dynamic访问System.Text.Json对象
    dotnet5将asp.net webapi宿主到wpf
    Asp.Net5 MVC with Vue.js
    在 Visual Studio 中使用跟踪点将信息记录到“输出”窗口中
    WPF带阴影的无边框窗体
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9576384.html
Copyright © 2011-2022 走看看