P5958 【[POI2017]Sabotaż】
P5958 【[POI2017]Sabotaż】
题意描述
在一棵以1号节点为根节点的树上,有很多纯洁的白点,
BUT,突然有一个黑点出现(可能在任意位置)
它要染黑尽可能多的节点,而在一棵子树中,
只有当黑点的比例\(>x\)才可以染黑根节点(即整棵子树)
求x的最小值,使得整棵树中被染黑的节点数不超过\(k\)个
如果你看不懂请走传送门
算法分析
一道很裸的树形DP,但思路很巧
显然本题有以下性质:
- 最坏情况下,最开始的叛徒是叶子结点
- 因为一个节点被染黑了,一起为根节点的子树将全黑,所以最终被染黑的一定是一颗子树
先设计状态:\(f(i)\)表示使得\(i\)不变黑的最小\(x\)
易得:\(f(i)\)也是使得\(i\)变黑的最大\(x\)
可知\(f(i)\)仅与\(f(son{i})\)以及\(soni\)的大小有关(这里的\(soni\)表示\(i\)的子节点)
那么我们用\(sum(i)\)表示以\(i\)为根节点的子树的大小,\(sum(i)\)是需要提前用dfs预处理的
显然\(i\)被染黑仅必须满足以下两种情况:
- \(f(soni)<=x\),即\(i\)的某棵子树被染黑
- \(sum(soni)/(sum(i)-1)<=x\),即\(soni\)的被染黑足以导致\(i\)的被染黑
根据以上规律可以推出如下方程:
\(f(i)=max(f(i),min(f(soni),sum(soni)/(sum(i)-1)))\)(不会用LaTeX写公式的蒟蒻瑟瑟发抖)
取\(min\)是因为需要同时满足条件1和条件2,
取\(max\)是因为需要答案最优
(貌似貌似到这里就结束了呢)
其实还有以下三点细节需要注意:
- 对于叶子结点\(a\),显然有\(f(a)=1\)
- 对于\(ans\)当\(sum(a)<k\)时是不需要考虑的,因为它合法,所以即使它被染黑也无所谓
- 针对上一条结论,易得\(ans=max(ans,f(a))\),其中\(sum(a)>=k\)
然后就去快乐\(AC\)吧......
代码实现
警告:不要直接复制代码,如果你\(RE\)了你知道是为什么的
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#define maxn 500050
using namespace std;
int n,k,sum[maxn];
double f[maxn],ans;
vector<int>v[maxn];//用vector存图笑哈哈
void dfs(int now,int fa){
sum[now]=1;
for(int i=0;i<v[now].size();i++){
int to=v[now][i];
dfs(to,now);
sum[now]+=sum[to];
}//dfs预处理sum[]
if(sum[now]==1){f[now]=1.0;return;}//叶子结点的处理
for(int i=0;i<v[now].size();i++){
int to=v[now][i];
f[now]=max(f[now],min(f[to],(double)sum[to]/(sum[now]-1)));
}//dp
if(sum[now]>k) ans=max(ans,f[now]);//统计答案,注意if
return;
}
int main(){
scanf("%d %d",&n,&k);
int x;
for(int i=2;i<=n;i++){
scanf("%d",&x);
v[x].push_back(i);
}
dfs(1,0);
printf("%.8lf",ans);//注意精度问题
while(1){}//防作弊
return 0;
}
结语
安利dalao博客
(光速逃...
P5958 【[POI2017]Sabotaż】的更多相关文章
- 【POI2017||bzoj4726】Sabota?
上学期putsnan过了一次,这学期认真写了一遍…… #include<bits/stdc++.h> #define N 500010 using namespace std; ]; ,n ...
- 【POI2017||bzoj4726】Flappy Birds
外国人很良心的啊,这题比NOIP那题还简单…… 不用管他最后的位置,因为移动的次数肯定是恒定的,所以维护在每一个柱子的位置能飞到的范围,递推下去即可. #include<bits/stdc++. ...
- 【BZOJ4726】[POI2017]Sabota? 树形DP
[BZOJ4726][POI2017]Sabota? Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者 ...
- 【AR实验室】mulberryAR : ORBSLAM2+VVSION
本文转载请注明出处 —— polobymulberry-博客园 0x00 - 前言 mulberryAR是我业余时间弄的一个AR引擎,目前主要支持单目视觉SLAM+3D渲染,并且支持iOS端,但是该引 ...
- 【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...
- 【Machine Learning】KNN算法虹膜图片识别
K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 【.net 深呼吸】程序集的热更新
当一个程序集被加载使用的时候,出于数据的完整性和安全性考虑,程序集文件(在99.9998%的情况下是.dll文件)会被锁定,如果此时你想更新程序集(实际上是替换dll文件),是不可以操作的,这时你得把 ...
随机推荐
- centos7中nfs共享的配置方法
NFS是Network File System的缩写,即网络文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. 一.nfs为什么需要RPC? 因为NFS支持的功能很多,不同 ...
- 【Python】数字与运算符
数据类型与运算符 数字 / 浮点除 // 整数除 ** 乘方 多种混合类型运算数的运算会把整数转换为浮点数 除了 int 和 float,Python也支持其他类型的数字,例如 Decimal 或者 ...
- Python基础-列表、元组、字典、字符串(精简解析)
一.列表 =====================================================1.列表的定义及格式: 列表是个有序的,可修改的,元素用逗号隔开,用中括号包围的序列 ...
- 【转载】绕过CDN找到源站的思路
[原文:https://mp.weixin.qq.com/s/8NUvPqEzVjO3XbmCBukUvQ] 绕过CDN的思路 网上有很多绕过CDN的思路,但是存在很多问题,以下是收集并总结的思路.站 ...
- DOS批处理中%cd%与%~dp0的区别详解
转载:https://www.jb51.net/article/105325.htm DOS批处理中%cd%与%~dp0的区别详解 Windows下批处理中%cd%和%~dp0都能用来表示当前 ...
- matlab中nargin函数输入参数数目
来源:https://ww2.mathworks.cn/help/matlab/ref/nargin.html?searchHighlight=nargin&s_tid=doc_srchtit ...
- C++extern关键字理解
extern是一种"外部声明"的关键字,字面意思就是在此处声明某种变量或函数,在外部定义. 下面的示意图是我的理解. extern关键字的主要作用是扩大变量/函数的作用域,使得其它 ...
- Trie树【字典树】浅谈
最近随洛谷日报看了一下Trie树,来写一篇学习笔记. Trie树:支持字符串前缀查询等(目前我就学了这些qwq) 一般题型就是给定一个模式串,几个文本串,询问能够匹配前缀的文本串数量. 首先,来定义下 ...
- 初学者的Android移植:在Debian上建立一个稳定的构建环境
介绍 通过在chrooted环境中设置开发环境,避免依赖冲突和沙箱您的Android开发从您的Debian GNU/Linux系统.这是为通配符类别准备的,因为从源代码构建Android似乎没有在其他 ...
- 笔记本键盘按U键却变成了4
解答 笔记本键盘U盘变成了4,是因为你开启了小键盘功能.出现该问题,只要关闭小键盘功能即可,操作如下: 按住键盘下方的Fn,同时按住键盘顶部的F键中标有Numlk的键. 电脑屏幕出现解锁标志,小键盘功 ...