BZOJ 4726 [POI2017]Sabota?:树形dp
题意
某个公司有 $ n $ 个人,上下级关系构成了一个有根树。其中有个人是叛徒(这个人不知道是谁)。对于一个人, 如果他下属(直接或者间接, 不包括他自己)中叛徒占的比例超过 $ x $ ,那么这个人也会变成叛徒,并且他的所有下属都会变成叛徒。你要求出一个最小的 $ x $ ,使得最坏情况下,叛徒的个数不会超过 $ k $ 。$ (1 \leq k \leq n \leq 500000) $
题解
首先有一个显然的二分做法,然而不知道为什么会被卡……
于是考虑能不能 $ O(n) $ 做。
首先有两个结论:
- 最坏情况下,最初的那一个叛徒一定是叶子结点。
- 如果一个非叶子节点叛变,则它其中的一个儿子一定叛变
所以最终所有的叛徒一定是原树中的一棵子树。
$ f[i] $ 表示要使节点 $ i $(及其下属)恰好不能叛变的最小比例 $ x $
因为所有 $ size[i] > k $ 的子树都不能叛变
所以 $ ans = max(f[i]) \quad (size[i] > k) $
然后考虑怎样求 $ f[i] $
$ f[i] $ 也等价于恰好让 $ i $ 叛变的最大比例 $ x $
对于每一个 $ i $ ,首先枚举它的哪个子树叛变了(假设是 $ j $ )
那么想让 $ i $ 叛变有两个条件:
- 比例 $ x $ 满足能够让 $ j $ 叛变
- 比例 $ x $ 满足 $ \dfrac{size[j]}{size[i] - 1} > x $
所以 $ f[i] = max(f[i], min(f[j], \dfrac{size[j]}{size[i]-1})) $
边界条件为:$ f[i] = \begin{cases} 1 \quad \text{叶子结点} \\ 0 \quad \text{非叶子节点} \end{cases} $
AC Code
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 500005
using namespace std;
int n,k;
int siz[MAX_N];
double ans=0;
double f[MAX_N];
vector<int> edge[MAX_N];
void read()
{
scanf("%d%d",&n,&k);
int x;
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
edge[x].push_back(i);
}
}
void dfs(int x)
{
siz[x]=1,f[x]=(edge[x].size()==0);
for(int i=0;i<edge[x].size();i++)
{
int t=edge[x][i];
dfs(t),siz[x]+=siz[t];
}
for(int i=0;i<edge[x].size();i++)
{
int t=edge[x][i];
f[x]=max(f[x],min(f[t],siz[t]/(siz[x]-1.0)));
}
if(siz[x]>k) ans=max(ans,f[x]);
}
void work()
{
dfs(1);
printf("%.9f\n",ans);
}
int main()
{
read();
work();
}
BZOJ 4726 [POI2017]Sabota?:树形dp的更多相关文章
- BZOJ 4726: [POI2017]Sabota? 树形dp
4726: [POI2017]Sabota? 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4726 Description 某个公司有n ...
- BZOJ 4726: [POI2017]Sabota?
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 301 Solved ...
- 【BZOJ4726】[POI2017]Sabota? 树形DP
[BZOJ4726][POI2017]Sabota? Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者 ...
- [bzoj4726][POI2017][Sabota?] (树形dp)
Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者间接, 不包括他自己)中叛徒占的比例超过x,那么这个人 ...
- BZOJ 4726 POI 2017 Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- Bzoj 1131[POI2008]STA-Station (树形DP)
Bzoj 1131[POI2008]STA-Station (树形DP) 状态: 设\(f[i]\)为以\(i\)为根的深度之和,然后考虑从他父亲转移. 发现儿子的深度及其自己的深度\(-1\) 其余 ...
- bzoj 2286(虚树+树形dp) 虚树模板
树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5002 Sol ...
- BZOJ 4472 [Jsoi2015]salesman(树形DP)
4472: [Jsoi2015]salesman Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 417 Solved: 192[Submit][St ...
- BZOJ 4890: [Tjoi2017]城市 树形dp
标签:树形dp,枚举,树的直径 一上来看到这个题就慌了,只想到了 $O(n^3)$ 的做法. 碰到这种题时要一步一步冷静地去分析,观察数据范围. 首先,$n\leqslant 5000$,所以可以先 ...
随机推荐
- C# 利用StringBuilder提升字符串拼接性能
一个项目中有数据图表呈现,数据量稍大时显得很慢. 用Stopwatch分段监控了一下,发现耗时最多的函数是SaveToExcel 此函数中遍列所有数据行,通过Replace替换标签生成Excel行,然 ...
- 视频流协议HLS与RTMP 直播原理 点播原理
小结: 1.HLS原理 视频--->图像.声音分别编码打包切割容器文件ts,建立纯文本索引文件.m3u8--->播放器http下载容器文件.索引文件,播放,下载 基于HLS可以实现直播和点 ...
- MongoDB-3: 查询(一)
一.简介 MongoDB提供了db.collection.find() 方法可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段. 二.db.collection.fi ...
- Event对象、队列、multiprocessing模块
一.Event对象 线程的一个关键特性是每个线程都是独立运行且状态不可预测.如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就 会变得非常棘手.为了解决这些问题, ...
- Leetcode 之 Exclusive Time of Functions
636. Exclusive Time of Functions 1.Problem Given the running logs of n functions that are executed i ...
- (4.8)SET ANSI_NULLS ON、SET QUOTED_IDENTIFIER ON
T-SQL支持在与空值进行比较时,允许比较运算符返回 TRUE 或 FALSE. 通过设置 ANSI_NULLS OFF 可将此选项激活.当 ANSI_NULLS 为 OFF 时,如果 ColumnA ...
- ionic学习笔记—常用命令
Ionic CLI介绍 Ionic CLI是开发Ionic应用程序过程中使用的主要工具.它就像一个瑞士军刀:它在一个界面下汇集了大量工具. CLI包含许多对Ionic开发至关重要的命令,例如start ...
- 使用jqueryUI和corethink实现的类似百度的搜索提示
代码:http://download.csdn.net/detail/u012995856/9676845 效果: 目录: 这里是以corethink模块的形式,只需要安装上访问 index.php? ...
- Python(迭代、三元表达式、列表生成、生成器、迭代器)
迭代 什么是迭代 1 重复 2 下次重复一定是基于上一次的结果而来 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). ...
- WCF RIA SERVICE相关技术
WCF RIA SERVICE实体属性拷贝 private void DoSubmit() { ((IEditableObject)this.RepairContract).EndEdit(); va ...