BZOJ 3252: 攻略 贪心 树链剖分
来源:互联网 发布:阿里云tts 编辑:程序博客网 时间:2024/06/07 22:50
3252: 攻略
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 541 Solved: 233
[Submit][Status][Discuss]
Description
题目简述:树版[k取方格数]
众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏。
今天他得到了一款新游戏《XX半岛》,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景。所有场景和选择支构成树状结构:开始游戏时在根节点(共通线),叶子节点为结局。每个场景有一个价值,现在桂马开启攻略之神模式,同时攻略k次该游戏,问他观赏到的场景的价值和最大是多少(同一场景观看多次是不能重复得到价值的)
“为什么你还没玩就知道每个场景的价值呢?”
“我已经看到结局了。”
Input
第一行两个正整数n,k
第二行n个正整数,表示每个场景的价值
以下n-1行,每行2个整数a,b,表示a场景有个选择支通向b场景(即a是b的父亲)
保证场景1为根节点
Output
输出一个整数表示答案
Sample Input
5 2
4 3 2 1 1
1 2
1 5
2 3
2 4
4 3 2 1 1
1 2
1 5
2 3
2 4
Sample Output
10
HINT
对于100%的数据,n<=200000,1<=场景价值<=2^31-1
Source
dfs序+线段树
有很多写dfs+线段树的 就是上面的hint....
先说这个做法
很明显 每次贪心选择权值最大的链是最优的策略
然后每个点删除后会影响它的子树
所以就是想怎么维护
之后BJ卡了一下 后来又想到每个点只能被访问一次
然后就发现自己十分low
只需要暴力从叶子向上跳就好了,到被访问过的点就停止
那线段树或树状数组维护一下权值就行了
但是这个题还是有其他的想法的
既然已经解决了子树向上跳的问题,又知道每次会选择到根路径上权值最大的叶子
所以不妨令子节点中向下可延伸权值和最大的点为重儿子,这样剖成的链就是每次选的链了
仍然贪心选就可以了
方法二的代码
#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=200100;int last[N],ecnt;struct EDGE{int to,nt;}e[N];inline void add(int u,int v){e[++ecnt]=(EDGE){v,last[u]};last[u]=ecnt;}int son[N],V[N];ll mx[N];void dfs1(int u){for(int i=last[u];i;i=e[i].nt){dfs1(e[i].to);if(mx[e[i].to]>mx[u])son[u]=e[i].to,mx[u]=mx[e[i].to];}mx[u]+=V[u];}ll sum[N];priority_queue<ll>q;void dfs2(int u){sum[son[u]]+=sum[u]+V[u];if(son[u])dfs2(son[u]);else q.push(sum[u]+V[u]);for(int i=last[u];i;i=e[i].nt){if(e[i].to==son[u])continue;dfs2(e[i].to);}sum[u]+=V[u];}int main(){int n=read(),K=read();ll ans=0;register int i,u,v;for(i=1;i<=n;++i)V[i]=read();for(i=1;i<n;++i){u=read();v=read();add(u,v);}dfs1(1);dfs2(1);while(!q.empty()&&K--){ans+=q.top();q.pop();}cout<<ans<<endl;return 0;}/*5 24 3 2 1 11 21 52 32 410*/
阅读全文
0 0
- BZOJ 3252: 攻略 贪心 树链剖分
- 【贪心】 BZOJ 3252:攻略
- bzoj 3252 攻略(长链剖分 + 贪心)
- 【BZOJ】【P3252】【攻略】【题解】【贪心+dfs序+线段树】
- BZOJ 3235 攻略 贪心+线段树+dfs序列
- BZOJ 3252 攻略 线段树
- BZOJ 3252攻略 dfs序+线段树
- bzoj 3252: 攻略 (线段树+DFS序)
- 【贪心】【bzoj 3008】: 象棋
- bzoj 1696 贪心
- BZOJ 3721 贪心
- bzoj 1034 泡泡堂|贪心
- BZOJ 4027 贪心
- [贪心] BZOJ 2697 特技飞行
- BZOJ 1193 搜索+贪心
- BZOJ 2151 种树 贪心
- BZOJ 4582 贪心
- bzoj 1572 贪心
- MySQL日期格式化函数
- 《Spring Boot in Action》【1. 起步】
- centos卸载docker
- 阿里云批量计算心得
- android 更新api current.txt
- BZOJ 3252: 攻略 贪心 树链剖分
- 服务器安全管理总结
- 7.3霍夫变换
- 由index_merge引发的死锁事件
- IE7下设置overflow-y: scroll出现滚动条的问题解决办法
- Map自定义键时注意事项
- java避开基本数据类型转换列表陷阱
- 注册邮箱验证激活技术
- ORM框架学习总结