首页 > 其他分享 >P6748 Fallen Lord [树形DP]

P6748 Fallen Lord [树形DP]

时间:2024-10-12 17:01:47浏览次数:1  
标签:tmp le int 边权 P6748 fa Fallen DP deg

P6748 Fallen Lord

Description

给定 \(n\) 个节点的树,每个点有点权 \(a_i\),求构造一组边权,使得每个点连接的边的边权的中位数不超过其点权,且每条边权不超过给定的 \(m\),输出边权之和的最大值。

一个升序序列 \(A=\{A_1,A_2,A_3...A_n\}\) 的中位数定义为 \(A_{\lfloor n/2\rfloor +1}\)。

\(n\le 5\times 10^5\),\(a_i\le m\le 10^9\)。

Solution

一个序列的中位数不超过 \(x\),相当于这个序列至少有 \(\lfloor n/2\rfloor+1\) 个元素不超过 \(x\)。

根据以上性质,可知一个边的边权有大于和不大于两种状态,且这个边权只和 两边的端点 以及 这些端点的其他边 有关,那么我们尝试去表达这种状态。

又根据题面,我们尝试考虑树形DP。

设 \(f(u,0/1)\) 表示以 \(u\) 为根的子树的答案,且边 \((u,fa_u)\) 的边权 不大于或大于 \(a_u\),
\(g(u,0/1)\) 表示以 \(u\) 为根的子树 加上 边 \((u,fa_u)\) 的答案,且边 \((u,fa_u)\) 的边权 不大于或大于 \(a_{fa_u}\),
至此,我们表示出了点与边的关系,然后考虑如何转移。

设 \(d_u\) 表示点 \(u\) 的度数,\(x=\lfloor d_u/2\rfloor+1\),\(v\in son_u\),

  • \(\sum g(v,0/1)\to f(u,0)\) :

    • 由于 \((u,fa_u)\) 已经不超过 \(a_u\) 了,那么还需要 \(x-1\) 条边不超过 \(a_u\) 才能满足条件,也就是最多可以有 \(d_u-x\) 条边大于 \(a_u\),那么我们只需要从所有 \(g(u,0/1)\) 中选出一个最优的满足这个条件的方案即可。考虑按照 \(g(v,1)-g(v,0)\) 降序排序,贪心的选前面不超过 \(d_u-x\) 个且差值大于 \(0\) 的 \(g(v,1)\) 转移到 \(f(u,0)\),后面的全部选 \(g(v,0)\) 即可。
  • \(\sum g(v,0/1)\to f(u,1)\) 类似。

  • 对于 \(g(u,0/1)\) 我们分类讨论 :

    • \(a_u > a_{fa_u}\) :
      • \(g(u,0)\) :\(a_u>a_{fa_u}\ge (u,fa_u)\),\(\to\ = f(u,0)+a_{fa_u}\)。
      • \(g(u,1)\) :\(a_u\ge(u,fa_u)>{fa_u}\) 或 \(m\ge (u,fa_u) > a_u > a_{fa_u}\),\(\to\ =\max\{f(u,0)+a_u,\ f(u,1)+m\}\)。
    • \(a_u\le a_{fa_u}\) :
      • \(g(u,0)\) :\((u,fa_u)\le a_u\le a_{fa_u}\) 或 \(a_u < (u,fa_u)\le a_{fa_u}\),\(\to\ =\max\{f(u,0)+a_u,\ f(u,1)+a_{fa_u}\}\)。
      • \(g(u,1)\) :\(a_u\le a_{fa_u}<(u,fa_u)\le m\),\(\to\ =f(u,1)+m\)。
  • 特殊情况:当 \(d_u\le 2\) 时,显然 \(f(u,1)\) 无法转移,设为 \(-\inf\) 即可。

  • 答案:\(f(1,0)\)。

于是,这道题就做完了。

Code

const int N = 5e5 + 5;
const ll inf = 1e18;

int n;
ll m, a[N];
int deg[N];
vector <int> e[N];

void adde(int u, int v) {e[u].ps(v);}

ll f[N][2], g[N][2];

void dfs(int u, int fa){
    vector <pair<ll, int> > tmp;

    for(int v : e[u]){
        if(v == fa) continue;
        dfs(v, u);
        tmp.ps(mk(g[v][1] - g[v][0], v));
    }

    sort(tmp.begin(), tmp.end(), greater <pair<ll, int> > ());

    int k = deg[u] - deg[u] / 2 - 1;
    for(int i = 0; i < tmp.size(); i++){
        auto [w, v] = tmp[i];
        if(i < k && w > 0) f[u][0] += g[v][1];
        else f[u][0] += g[v][0];
        if(i < k - 1 && w > 0) f[u][1] += g[v][1];
        else f[u][1] += g[v][0];
    }

    if(deg[u] <= 2) f[u][1] = -inf;
    
    if(a[u] > a[fa]){
        g[u][0] = f[u][0] + a[fa];
        g[u][1] = max(f[u][0] + a[u], f[u][1] + m);
    }else{
        g[u][0] = max(f[u][0] + a[u], f[u][1] + a[fa]);
        g[u][1] = f[u][1] + m;
    }
}

void Solve(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    int u, v;
    for(int i = 1; i <= n - 1; i++){
        cin >> u >> v;
        deg[u]++;
        deg[v]++;
        adde(u, v);
        adde(v, u);
    }

    dfs(1, 0);

    cout << f[1][0] << endl;
}

标签:tmp,le,int,边权,P6748,fa,Fallen,DP,deg
From: https://www.cnblogs.com/chenwenmo/p/18460881

相关文章

  • C#线程---ThreadPool
    线程池的简介   为每个短暂的异步操作创建线程会产生显著的开销,线程池可以成功地适应于任何需要大量短暂的开销大的资源的情形。我们事先分配一定的资源,将这些资源放入到资源池。每次需要新的资源.只需从池中获取一个,而不用创建一个新的。当该资源不再被使用时,就将其返......
  • .NET MAUI 手搓 UDP/TCP 通信
    在.NETMAUI中,UDP和TCP是网络通信协议,与MAUI框架本身的关系在于.NETMAUI可以利用.NET的网络功能来实现跨平台的网络通信。.NET提供的System.Net.Sockets命名空间来处理。该命名空间提供了创建和管理套接字(Sockets)来进行网络通信的相关类和方法。在.NETMAUI......
  • c# winform 高 dpi 自适应开发步骤
    1.在不启用dpiaware模式下开发2.启动dpiaware3.对有问题的控件使用 DpiHelper对定位和大小或者图像进行转换参见 解决DPI问题-VisualStudio(Windows)|MicrosoftLearn部分官方示例:若要从将在VisualStudio环境中运行的托管代码访问DPI帮助程序函数,请......
  • E65 树形DP P3237 [HNOI2014] 米特运输
    视频链接:E65树形DPP3237[HNOI2014]米特运输_哔哩哔哩_bilibili  P3237[HNOI2014]米特运输-洛谷|计算机科学教育新生态(luogu.com.cn)//树形DPO(n)#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=500005,mod=1e9+7;......
  • E64 树形DP P3174 [HAOI2009] 毛毛虫
    视频链接:E64树形DPP3174[HAOI2009]毛毛虫_哔哩哔哩_bilibili  P3174[HAOI2009]毛毛虫-洛谷|计算机科学教育新生态(luogu.com.cn)//树形DPO(n)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;constintN=300005;int......
  • dp内启用第三方软件方法
    dp内启用第三方软件方法使用代码方法,需要SSH到终端进行:1.下载需要的app,以com.autonavi.amapauto.apk为例cd/data/&&gitclonehttps://github.com/dragonpilot-community/apps.gitapps-bcom.autonavi.amapauto.apk 在sdard内新建文件夹apks文件夹cd/sda......
  • 在Linux中搭建WordPress并实现Windows主机远程访问
      WordPreWordPress是一个基于PHP开发的开源平台,适用于在支持PHP与MySQL数据库的服务器上搭建个性化博客或网站。同时,它也能够作为功能强大的内容管理系统(CMS)被广泛应用。虚拟机:VirtualBox虚拟机安装......
  • 区间dp板子
    比较简单的dp,但是建模可能会比较困难。以P1775石子合并(弱化版)为例(https://www.luogu.com.cn/problem/P1775)思路:要求1-n的石子合并的代价,可以看成小的区间问题,化为1-k+k-n的两个区间。然后就有递推式子:dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+w[j]-w[i-1]。编......
  • ABC292G Count Strictly Increasing Sequences [区间DP]
    Description你有\(n\)个数,每个数长度为\(m\)。不过这\(n\)个数中,可能有某些位不确定,需要你在每个?位置上\(0\)到\(9\)之间填一个数。设你填出来的序列是\(\{S_i\}\)。请你求出,在所有可能的填数方案中,有多少种满足\(S_1<S_2<\dots<S_n\)?对\(998244353\)取......
  • 【刷题笔记】DP 2021.10.11
    Candies思路朴素的算法设\(f_{i,j}\)表示给前\(i\)个小朋友分\(j\)个糖的方案数,\[f_{i,j}=\sum_{k=0}^{min(a[i],j)}f_{i-1,j-k}\]注意到此时时间复杂度为\(O(n\timesk^2)\)想到用前缀和进行优化,设\(s_{i,j}\)表示\(\sum_{j=0}^{k}f_{i,j}\)则\(DP\)转移方程\[f_{i,j}=s_......