1 条题解
-
0
自动搬运
来自洛谷,原作者为

nofind
苟到省选退役的蒟蒻搬运于
2025-08-24 21:50:19,当前版本为作者最后更新于2019-09-27 19:14:30,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意:https://www.luogu.org/problem/P3574
表示子树内的最大值,表示走完的子树后回到的总时间
(存的是走完y之前的子树后回到的时间)(是从到的花费)
但是这样f的取值和遍历子树的顺序有关,于是考虑贪心
对于两个相邻(遍历时)的子树和,前,后
不交换:
交换:
如果交换比不交换优:
由于
所以上式即为:
转化一下即为:
排序即可
注意最后和size[1]+val[1]取max
code:
#include<bits/stdc++.h> using namespace std; const int maxn=5000010; int n,cnt; int val[maxn],head[maxn],f[maxn],size[maxn],tmp[maxn]; struct edge { int to,nxt; }e[maxn<<1]; inline bool cmp(int x,int y){return size[x]-f[x]<size[y]-f[y];} inline void add(int u,int v) { e[++cnt].nxt=head[u]; head[u]=cnt; e[cnt].to=v; } void dfs(int x,int fa) { if(x!=1)f[x]=val[x]; for(int i=head[x];i;i=e[i].nxt)if(e[i].to!=fa)dfs(e[i].to,x); int tot=0; for(int i=head[x];i;i=e[i].nxt)if(e[i].to!=fa)tmp[++tot]=e[i].to; sort(tmp+1,tmp+tot+1,cmp); for(int i=1;i<=tot;i++)f[x]=max(f[x],f[tmp[i]]+size[x]+1),size[x]+=size[tmp[i]]+2; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&val[i]); for(int i=1;i<n;i++) { int u,v;scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs(1,0); printf("%d",max(f[1],size[1]+val[1])); return 0; }
- 1
信息
- ID
- 2647
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者