zoukankan      html  css  js  c++  java
  • Sabota?

    Sabota?

    题目描述

     

    某个公司有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以内都被认为是正确的。

     

    样例输入

    <span style="color:#333333"><span style="color:#333333">9 3
    1
    1
    2
    2
    2
    3
    7
    3</span></span>

    样例输出

    <span style="color:#333333"><span style="color:#333333">0.6666666667</span></span>

    提示

     

    HINT

    答案中的x实际上是一个无限趋近于2/3但是小于2/3的数

    因为当x取2/3时,最坏情况下3,7,8,9都是叛徒,超过了k=3。

     

    来源

    POI2017


    solution

    首先叛变的点应该出现在叶子,因为如果中间的点叛变导致了连环,那么叶子的点叛变一定也能导致连环。

    我们要求一个最小的x使得叛变数<=k

    令f[i]表示让以i为根的子树叛变的最大的x

    那么有f[i]=max(所有e[i].v) min(f[e[i].v],size[e[i].v]/size[k]-1);

    就是他的儿子叛变且儿子会带动他叛变

    树形dp,数据有点卡

    当时想不清楚就写,一直错

    引用神犇的话 think twice,code once

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define db double
    #define maxn 500005
    using namespace std;
    int n,kk,head[maxn],sz[maxn],t,tot;
    db f[maxn],Max;
    struct node{
        int v,nex;
    }e[maxn];
    void lj(int t1,int t2){
        e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
    }
    void dfs(int k){
        for(int i=head[k];i;i=e[i].nex)dfs(e[i].v),sz[k]+=sz[e[i].v];
        sz[k]++;
    }
    void work(int k){
        bool fl=0;
        for(int i=head[k];i;i=e[i].nex){
            work(e[i].v);fl=1;
            f[k]=max(f[k],min(f[e[i].v],(db)sz[e[i].v]/(sz[k]-1)));
        }
        if(!fl)f[k]=1;
        if(sz[k]>kk)Max=max(Max,f[k]);
    }
    int main(){
        cin>>n>>kk;
        //if(n==1) 
        for(int i=2;i<=n;i++){
            scanf("%d",&t);
            lj(t,i);
        }
        dfs(1);
        Max=0;for(int i=1;i<=n;i++)f[i]=0;
        work(1);
        if(Max==0)puts("0"); 
        else printf("%.10lf
    ",Max);
        //rubbish problem
        // a waste of ac rate
        return 0;
    }
     
  • 相关阅读:
    第十周作业--阅读(五一)
    第九周作业
    第八周作业
    第七周作业
    第六周作业
    模板
    第五周作业
    第四周作业
    第三周作业
    文件
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358808.html
Copyright © 2011-2022 走看看