[POI2017]Sabota【观察+树形Dp】
Online Judge:Bzoj4726
Label:观察,树形Dp,水题
题目描述
某个公司有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}\)以内都被认为是正确的。
样例
Input
9 3
1
1
2
2
2
3
7
3
Output
0.6666666667
Hint
当x取2/3时,最坏情况下3,7,8,9都是叛徒,超过了k=3。
答案中的x实际上是一个无限趋近于2/3但是大于2/3的数。
题解
看样例知道实际上是求一个转变的临界值。
观察一下发现,要叛变就是整个子树一起叛变,而且因为只选了一个叶子节点做叛徒,所以只会有这唯一一棵树叛变——不会出现多棵不相关的子树同时叛变。
那么我们只需要算出以每个点为根的子树叛变时所需的最大叛变比例\(lim[i]\)即可。上面这个定义有点繁琐,本质是比例\(lim\)调大,子树叛变越难。我们就是求一个最大值,使得在这个比例下,子树刚好叛变,如果提高一点就叛变不了了。
求\(lim\)的方法类似树形dp。
最后统计时的代码如下,其中\(siz\)表示子树大小。求其中的最大值,因为比例达到这个最大值时,这些\(siz>k\)的子树都叛变不了(如果叛变了就不合法了)。
double ans=0;
for(int i=1;i<=n;i++)if(siz[i]>k)ans=max(ans,lim[i]);
printf("%.7f",ans);
完整代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
vector<int>e[N];
int n,k,siz[N];
double lim[N];//i的子树中叛变,能让i也叛变的最大k值
void dfs(int x){
siz[x]=1;
for(int i=0;i<e[x].size();i++)dfs(e[x][i]),siz[x]+=siz[e[x][i]];
if(siz[x]==1)lim[x]=1.0;
for(int i=0;i<e[x].size();i++){
int y=e[x][i];
lim[x]=max(lim[x],min(lim[y],1.0*siz[y]/(siz[x]-1.0)));
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=2,u;i<=n;i++){
scanf("%d",&u);
e[u].push_back(i);
}
dfs(1);
double ans=0;
for(int i=1;i<=n;i++)if(siz[i]>k)ans=max(ans,lim[i]);
printf("%.7f",ans);
}
[POI2017]Sabota【观察+树形Dp】的更多相关文章
- BZOJ_4726_[POI2017]Sabota?_树形DP
BZOJ_4726_[POI2017]Sabota?_树形DP Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属 ...
- BZOJ 4726 [POI2017]Sabota?:树形dp
传送门 题意 某个公司有 $ n $ 个人,上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他下属(直接或者间接, 不包括他自己)中叛徒占的比例超过 $ x $ , ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- BZOJ 4726: [POI2017]Sabota? 树形dp
4726: [POI2017]Sabota? 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4726 Description 某个公司有n ...
- 【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 ...
- 树形dp专题总结
树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...
- BZOJ 4726: [POI2017]Sabota?
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 301 Solved ...
随机推荐
- Google Projectsheet Planning 插件的WBS
生成 WBS的序列號 在 Sldebar中的 "WBS" 按鈕: "< WBS" 取消下級目錄 "WBS >" 生成下級目錄 G ...
- CSIC_716_20191116【常用模块的用法 time ,datetime, random, os, sys, hashlib】
import time import datetime import os import sys import random import hashlib time模块 时间戳(Timestamp) ...
- soj考试2
T1:子图 给你一棵带点权的树,对于所有i∈[1,m],问树上是否存在连通子图的权值和=i? n<=3000,m<=100000. 朴素的背包树形dp有nm的复杂度,bitset也无处优化 ...
- 学无止境,我爱python
每天更新.... python基础 python字符编码 python基础数据类型 python列表.元组 python字典 python字符编码unicode,utf-8,ascii python深 ...
- 三模数NTT模板
求两个多项式的卷积对任意数p取模 两个好记的FNT模数: 5*2^25+1 7*2^26+1 原根都为3 //Achen #include<algorithm> #include<i ...
- HTML5: 实现调用系统拍照或者选择照片并预览
ylbtech-HTML5: 实现调用系统拍照或者选择照片并预览 1.返回顶部 1. <!DOCTYPE html> <html> <head> <meta ...
- 17.splash_case06_ScrapySplashTest-master
taobao.py # -*- coding: utf-8 -*- from scrapy import Spider, Request from urllib.parse import quote ...
- 16.ajax_case09
import requests import json import re from selenium import webdriver from selenium.webdriver.common. ...
- python常用包及功能介绍
1.NumPy数值计算 NumPy是使用Python进行科学计算的基础包,Numpy可以提供数组支持以及相应的高效处理函数,是Python数据分析的基础,也是SciPy.Pandas等数据处理和科学计 ...
- SF Symbols 使用
伴随着WWDC 2019 的举办,对于程序员而言 ,无疑SwiftUI 推出 是比较令人兴奋的一件事情, 其中在SwiftUI 使用之中, 我们经常使用以下系统图片 Image(systemName: ...