题解 \(by\;zj\varphi\)

首先,分析一下这个答案:本质上是求在一条路径上,选择了一些点,这些点的贡献是它周围的点权和 - 它上一步的点权

对于一棵树,可以先确定一个根,然后每条路径就可以分成向上和向下的两部分

那么定状态 \(dp_{i,j,0}\) 表示由 \(i\) 向 \(i\) 的子树走,选了 \(j\) 个点放磁铁,\(dp_{i,j,1}\) 则表示向上走

那么转移方程就很好想

\[dp_{i,j,0}=\max\{dp_{son\in son_i,j,0},dp_{son\in son_i,j-1,0}+sum_x-num_{son}\}
\]
\[dp_{i,j,1}=\max\{dp_{son\in son_i,j,1},dp_{son\in son_i,j-1,1}+sum_x-num_{fa}\}
\]

这个方程就是由下往上转移,且对于一个放了的点,它上一个经过的点无法被它管到。

初始化时要把 \(dp_{x,i,0}\) 都初始化为 \(sum_x\),因为转移时可以是一个点加上一条向下的路径。

转移答案时要注意:对于一个节点的所有儿子要从前往后转移一遍,同时从后往前转移一遍,这样才能保证所有分支都有可能向下或向上。

还要在逆向转移之前恢复 \(dp\) 数组原有状态。

Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
typedef long long ll;
static const int N=1e5+7;
int first[N],nm[N],tmp[N],cnt,t=1,n,vn;
struct edge{int v,nxt;}e[N<<1];
inline void add(int u,int v) {
e[t].v=v,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].nxt=first[v],first[v]=t++;
}
ll dp[N][107][2],ans,sum[N];
inline void update(int x,int v,int fa) {
for (ri i(1);i<vn;p(i)) ans=cmax(ans,dp[x][i][0]+dp[v][vn-i][1]);
for (ri i(1);i<=vn;p(i)) {
dp[x][i][0]=cmax(dp[x][i][0],cmax(dp[v][i][0],dp[v][i-1][0]+sum[x]-nm[v]));
dp[x][i][1]=cmax(dp[x][i][1],cmax(dp[v][i][1],dp[v][i-1][1]+sum[x]-nm[fa]));
}
}
void dfs(int x,int fa) {
for (ri i(first[x]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==fa) continue;
dfs(v,x);
}
for (ri i(1);i<=vn;p(i)) dp[x][i][0]=sum[x];
cnt=0;
for (ri i(first[x]);i;i=e[i].nxt) update(x,tmp[p(cnt)]=e[i].v,fa);
for (ri i(1);i<=vn;p(i)) dp[x][i][0]=sum[x],dp[x][i][1]=0;
for (ri i(cnt);i;--i) update(x,tmp[i],fa);
ans=cmax(ans,cmax(dp[x][vn][1],dp[x][vn][0]));
}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
// printf("cost = %d\n",sizeof(dp)>>20);
read(n),read(vn);
for (ri i(1);i<=n;p(i)) read(nm[i]);
for (ri i(1),u,v;i<n;p(i)) {
read(u),read(v);
add(u,v);
}
for (ri i(1);i<=n;p(i)) {
for (ri j(first[i]),v;j;j=e[j].nxt) sum[i]+=nm[e[j].v];
}
dfs(1,0);
printf("%lld\n",ans);
return 0;
}
}
int main() {return nanfeng::main();}

NOIP 模拟 $21\; \rm Park$的更多相关文章

  1. NOIP 模拟 $21\; \rm Game$

    题解 考试的时候遇到了这个题,没多想,直接打了优先队列,但没想到分差竟然不是绝对值,自闭了. 正解: 值域很小,所以我们开个桶,维护当前最大值. 如果新加入的值大于最大值,那么它肯定直接被下一个人选走 ...

  2. NOIP 模拟 $21\; \rm Median$

    题解 \(by\;zj\varphi\) 对于这个序列,可以近似得把它看成随机的,而对于随机数列,每个数的分布都是均匀的,所以中位数的变化可以看作是常数 那么可以维护一个指向中位数的指针,同时维护有多 ...

  3. NOIP模拟3

    期望得分:30+90+100=220 实际得分:30+0+10=40 T1智障错误:n*m是n行m列,硬是做成了m行n列 T2智障错误:读入三个数写了两个%d T3智障错误:数值相同不代表是同一个数 ...

  4. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  5. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  6. NOIP 模拟 $38\; \rm c$

    题解 \(by\;zj\varphi\) 发现就是一棵树,但每条边都有多种不同的颜色,其实只需要保留随便三种颜色即可. 直接点分治,将询问离线,分成一端为重心,和两端都不为重心的情况. 每次只关心经过 ...

  7. NOIP 模拟 $36\; \rm Cicada 拿衣服$

    题解 \(by\;zj\varphi\) 发现右端点固定时,左端点的 \(min-max\) 单调递减,且对于 \(or\) 和 \(and\) 相减,最多有 \(\rm2logn\)个不同的值,且相 ...

  8. NOIP 模拟 $36\; \rm Dove 打扑克$

    题解 \(by\;zj\varphi\) 引理 对于一个和为 \(n\) 的数列,不同的数的个数最多为 \(\sqrt n\) 证明: 一个有 \(n\) 个不同的数的数列,和最小就是 \(n\) 的 ...

  9. NOIP 模拟 $34\; \rm Equation$

    题解 \(by\;zj\varphi\) 发现每个点的权值都可以表示成 \(\rm k\pm x\). 那么对于新增的方程,\(\rm x_u+x_v=k\pm x/0\) 且 \(\rm x_u+x ...

随机推荐

  1. CG-CTF 签到

    int __cdecl sub_401340(unsigned __int8 *a1) { int v2; // [esp+18h] [ebp-D0h] int v3; // [esp+1Ch] [e ...

  2. 查找----python

    class Solution: #顺序查找 def seq_search(self,list,num): for i in(range(len(list))): if list[i] == num: ...

  3. FTP服务—三种登录类型的配置方法

    目录 一.部署 二.配置vsftpd 1.匿名用户登录配置 2.系统用户登录配置 3.虚拟用户登录配置 1. 创建虚拟用户名单文件 2. 生成虚拟用户口令认证文件 3. 创建FTP根目录及虚拟用户映射 ...

  4. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

  5. 洛谷 P4008 [NOI2003]文本编辑器

    先推广一下 求赞 我们考虑这样的一个问题 给你一个序列,要求你支持插入,删除,查询单点值 如果用数组,查询O(1),插入删除最坏O(n) 如果用链表,插入删除O(1),查询最坏O(n) 如果用平衡树- ...

  6. Nacos入门学习&实践

    文中涉及到了一些模块代码没有给出,我一并上传到github了,可以整个项目clone下来进行调试. 地址:https://github.com/stronglxp/springcloud-test 1 ...

  7. C语言:编译具体过程及隐藏

    对于平常应用程序的开发,很少有人会关注编译和链接的过程,因为我们使用的工具一般都是流行的集成开发环境(IDE),比如 Visual Studio.Dev C++.C-Free 等.这些功能强大的 ID ...

  8. SpringBoot总结之Spring Data Jpa

    一.Spring Data Jpa简介 JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate.TopLink等. Spring D ...

  9. YARN学习总结之环境搭建

    Yarn环境搭建(基于hadoop-2.6.0-cdh5.7.0 伪分布) 1)配置文件 etc/hadoop/mapred-site.xml: <configuration> <p ...

  10. Eclipse配置反编译插件jadclipse

    参考自:https://blog.csdn.net/moneyshi/article/details/79715891 Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java ...