题目描述

离线题库请

题目描述

某个公司有\(n\)个人, 上下级关系构成了一个有根树。其中有个人是叛徒(这个人不知道是谁)。对于一个人, 如果他

下属(直接或者间接, 不包括他自己)中叛徒占的比例超过\(x\),那么这个人也会变成叛徒,并且他的所有下属都会变

成叛徒。你要求出一个最小的\(x\),使得最坏情况下,叛徒的个数不会超过\(k\)。

输入格式

第一行包含两个正整数\(n,k(1<=k<=n<=500000)\)。

接下来\(n-1\)行,第\(i\)行包含一个正整数\(p[i+1]\),表示\(i+1\)的父亲是\(p[i+1](1<=p[i+1]<=i)\)。

输出格式

输出一行一个实数\(x\),误差在\(10^-6\)以内都被认为是正确的。

自己想出来的\(QWQ\),刚开始想的是二分\(+dp\),但是最后搞出来的方程发现和题解差不多

题解

思路细想的话非常绕!!!不细想的话随便搞搞也能出来

首先考虑这么两个事儿

  1. 最坏情况一定是子节点是第一个叛徒;

    因为假如某节点\(i\)变成叛徒,他的父亲\(fa\)不会受影响,那么他的叶节点\(leaf\)变成叛徒,反而可能把以\(i\)为根的子树全变成叛徒,创造更多的叛徒,甚至把\(fa\)也变成叛徒
  2. 最坏情况一定是一棵子树全部是叛徒,而不会出现森林;

我们考虑树上\(dp\)

首先统计出子树\(i\)的大小

那么让这颗子树变成叛徒的条件是什么呢,宁先想着,我待会儿和宁说

一个子树变成叛徒的边界条件是啥呢,就是求使当前子树变成叛徒的最大\(x\),\(x\)再大一点点就不行了,我们把这个稍微大一点点的\(x\)叫做\(x_1\),而我们求的是不让子树大小大于\(k\)的\(x\)的最小值,宁想一想这俩东西的关系

可以发现我们要求的答案就是所有大小大于\(k\)的子树的\(x_1\)的最大值,又因为是稍微大一点点,所以我们想成一样大

然后就可以\(dp\)了

此时回到上面的问题,让一颗子树变成叛徒的条件就是有一棵他的儿子叛变,而且以儿子为根的子树的大小在可以整棵子树所占的比例大于等于当前节点叛变要求的\(x\)

这俩条件需要同时满足,所以我们求其中的较小值,即以下

 minn = min( dp[son], 1.0 * siz[v] / ( siz[now] - 1 ) )     // 注意乘1.0,如果( double )转高精的话取完min就会变成0,我WA了一上午

然后我们在它的每棵子树的\(minn\)中取一个最大值就是当前节点恰好叛变的\(x\),也是恰好不叛变的值

最后在每个大小大于\(k\)的子树的\(dp\)里取个最大值,就是恰好不让所有的大于\(k\)的子树叛变的\(x\)即答案

#include<bits/stdc++.h>
using namespace std;
#define rint register int
int n, k;
int b[500010];
double dp[500010], ans;
vector< int > vec[500010];
inline int read( void ){
int re = 0, f = 1; char ch = getchar();
while( ch > '9' || ch < '0' ){
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' ){
re = re * 10 + ch - '0';
ch = getchar();
}
return re * f;
}
inline void dfs( int now ){
b[now] = 1;
for( rint i = 0; i < vec[now].size(); i++ ){
int v = vec[now][i];
dfs( v );
b[now] += b[v];
}
dp[now] = ( b[now] == 1 );
if( b[now] != 1 ){
for( rint i = 0; i < vec[now].size(); i++ ){
int v = vec[now][i];
dp[now] = fmax( dp[now], fmin( dp[v], 1.0 * b[v] / ( b[now] - 1 ) ) );
}
}
if( b[now] > k ){
ans = max( ans, dp[now] );
}
}
int main( void ){
n = read(); k = read();
for( rint i = 2; i <= n; i++ ){
int u; u = read();
vec[u].push_back( i );
}
dfs( 1 );
cout << ans;
return 0;
}

数据点下载

[POI2017]bzoj4726 Sadota?的更多相关文章

  1. 【POI2017||bzoj4726】Sabota?

    上学期putsnan过了一次,这学期认真写了一遍…… #include<bits/stdc++.h> #define N 500010 using namespace std; ]; ,n ...

  2. 【POI2017||bzoj4726】Flappy Birds

    外国人很良心的啊,这题比NOIP那题还简单…… 不用管他最后的位置,因为移动的次数肯定是恒定的,所以维护在每一个柱子的位置能飞到的范围,递推下去即可. #include<bits/stdc++. ...

  3. 【BZOJ4726】[POI2017]Sabota? 树形DP

    [BZOJ4726][POI2017]Sabota? Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者 ...

  4. bzoj4726【POI2017】Sabota?

    首先可以推出来如果i没有带头叛变,那么i的父亲也一定不会带头叛变,证明显然 所以最劣情况初始的叛徒肯定是叶子,并且带头叛变的人一定是从某个叶子往上走一条链 f[i]表示i不带头叛变的话最小的x 那么我 ...

  5. 【树形dp】bzoj4726: [POI2017]Sabota?

    找点概率期望的题做一做 Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者间接, 不包括他自己)中叛徒占 ...

  6. BZOJ4726: [POI2017]Sabota?

    $n \leq 500000$的树,开始有一个点是坏的,如果一个子树中坏点比例(不包括根节点)超过x那这整棵子树就会变坏,问最坏情况下不超过$K$个坏点的情况下$x$最小是多少. 被坑成傻逼.. 可以 ...

  7. [bzoj4726][POI2017][Sabota?] (树形dp)

    Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属(直接或者间接, 不包括他自己)中叛徒占的比例超过x,那么这个人 ...

  8. BZOJ 4726: [POI2017]Sabota?

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 301  Solved ...

  9. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

随机推荐

  1. AD复制问题汇总

    1:文件复制服务NtFrs 13568报错的解决方法 解决方法: 建议不要按照日志的提示进行操作,正确的操作应该是 出现这个问题的原因,是由于在硬件的损坏,导致服务器未正确处理NTFS USN 日志. ...

  2. [LC] 362. Design Hit Counter

    Design a hit counter which counts the number of hits received in the past 5 minutes. Each function a ...

  3. 位移&二进制转换&原码&反码&补码

    << 左移 按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零. 格式 需要移位的数字 << 移位的次数 计算过程 1. 按二进制形式把所有的数字向左 ...

  4. Data Binding on Android

    Data Binbing框架是在2015年Google I/O大会上最早提出来的,一直在Android开发者中热议,但是很少有真正在项目中用到.本文简单介绍Data Binding框架的简单用法以及其 ...

  5. 别恐慌,大众关心的人工智能问题学界都在努力求解——我眼中的AAAI 2015大会

    2015大会" title="别恐慌,大众关心的人工智能问题学界都在努力求解--我眼中的AAAI 2015大会"> 作者:微软亚洲研究院副研究员 黄铂钧 今年是美国 ...

  6. python ATM项目

    1.需求: 指定最大透支额度 可取款 定期还款(每月指定日期还款,如15号) 可存款 定期出账单 支持多用户登陆,用户间转帐 支持多用户 管理员可添加账户.指定用户额度.冻结用户等 购物车: 商品信息 ...

  7. 使用Google App Engine开始新的网站开发学习

    继长时间的迷茫后,我发现还是回归php网站开发更适合我,或者没有那么深刻,但至少要做点事情.不知道以后将从事什么样的工作,但现在找点事情做还是很好的.所以,为了激发我学习的热情,我在网上搜了一下免费云 ...

  8. 日志框架之2 slf4j+logback实现日志架构 · 远观钱途

    如何从缤纷复杂的日志系统世界筛选出适合自己的日志框架以及slf4j+logback的组合美妙之处?此文可能有帮助 logback介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网 ...

  9. github hexo配置踩过的坑

    大体步骤:配置npm,在github中增加自己的sshkey. 多sshkey的话在用户主目录的.ssh中要配置好. 删除仓库里面 source/_posts/我的文章.md 执行下面命令更新博客 h ...

  10. css进阶之二:flex弹性布局

    布局模式是指一个盒子与其兄弟.祖先盒的关系决定其尺寸与位置的算法.css2.1中定义了四种布局模式,分别是块布局.行内布局.表格布局.以及定位布局.css3引入了新的布局模式Flexbox布局,灵活度 ...