博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【CodeM初赛B轮】A 贪心
阅读量:4964 次
发布时间:2019-06-12

本文共 1055 字,大约阅读时间需要 3 分钟。

【CodeM初赛B轮】A

题目大意:给你一棵树,起初所有点都是白色的,你每次都能选择一个白点i,将这个点i到根路径上的所有到i的距离<k[i]的点都染成黑色(根和i也算,已经被染成黑色的点还是黑色)。问最少需要染多少次才能将所有点都变黑。

n<=100000

题解:显然贪心啊,但是我一开始居然写了树剖。。。

因为叶子节点是一定要染的,所以我们可以将所有点按DFS序排序,从后往前染。记录vis[i],表示之前已经将所有到i的距离<=vis[i]的点染成了黑色;再维护mx[i],表示之前染过的点最多能将到i的距离<=mx[i]的点染成黑色。然后用当前的vis和mx去更新fa就行了。

#include 
#include
#include
using namespace std;const int maxn=100010;int n,cnt,ans;int fa[maxn],tag[maxn],k[maxn],p[maxn],head[maxn],nxt[maxn],to[maxn],ml[maxn];void add(int a,int b){ to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;}void dfs(int x){ p[++p[0]]=x; for(int i=head[x];i!=-1;i=nxt[i]) dfs(to[i]);}int main(){ scanf("%d",&n); int i,a; memset(head,-1,sizeof(head)); for(i=2;i<=n;i++) scanf("%d",&fa[i]),add(fa[i],i); for(i=1;i<=n;i++) scanf("%d",&k[i]); dfs(1); for(i=n;i>=1;i--) { a=p[i]; ml[a]=max(ml[a],k[a]); if(!tag[a]) tag[a]=ml[a],ans++; ml[fa[a]]=max(ml[fa[a]],ml[a]-1),tag[fa[a]]=max(tag[fa[a]],tag[a]-1); } printf("%d",ans); return 0;}

转载于:https://www.cnblogs.com/CQzhangyu/p/7077212.html

你可能感兴趣的文章
DataTable和 DataRow的 区别与联系
查看>>
检索COM 类工厂中CLSID 为 {00024500-0000-0000-C000-000000000046}的组件时失败
查看>>
mysql数据库中数据类型
查看>>
Fireworks基本使用
查看>>
两台电脑间的消息传输
查看>>
Linux 标准 I/O 库
查看>>
.net Tuple特性
查看>>
Java基础常见英语词汇
查看>>
iOS并发编程笔记【转】
查看>>
08号团队-团队任务5:项目总结会
查看>>
SQL2005 删除空白行null
查看>>
mysql备份与恢复
查看>>
混沌分形之迭代函数系统(IFS)
查看>>
边框圆角Css
查看>>
使用Busybox制作根文件系统
查看>>
jpg图片在IE6、IE7和IE8下不显示解决办法
查看>>
delphi之模糊找图
查看>>
Javascript模块化编程的写法
查看>>
oracle 使用job定时自动重置sequence
查看>>
在项目中加入其他样式
查看>>