zoukankan      html  css  js  c++  java
  • bzoj4726【POI2017】Sabota?

    首先可以推出来如果i没有带头叛变,那么i的父亲也一定不会带头叛变,证明显然

    所以最劣情况初始的叛徒肯定是叶子,并且带头叛变的人一定是从某个叶子往上走一条链

    f[i]表示i不带头叛变的话最小的x

    那么我们对所有子树大小>k的f值取max即是答案

    f[i]=max j为i的儿子 (min(f[j],siz[j]/(siz[i]-1))

    因为对于i的一个儿子j,假如i因为j的子树里的叛徒比例大于x而带头叛变,那么既要满足x<=(j的子树大小占i的子树大小的比例),还要满足j带头叛变即x<=f[j],所以对两个量取min

    那么如果i不叛变,那么就不能满足任意一个条件,所以对所有的取max

    对于叶子,f[i]=1,因为不管怎样叶子本身就是叛徒,可以视为不需要条件就可以带头叛变,即只有当x>1时才不会叛变

    某神犇博客:http://blog.csdn.net/neither_nor/article/details/53373065

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int Mx=500010;
    int n,k,tot,head[Mx],next[Mx],ver[Mx],siz[Mx];
    double f[Mx],ans;
    inline void add(int x,int y)
    {  
        next[++tot]=head[x];
        ver[tot]=y;
        head[x]=tot;  
    }
    void dfs(int x)
    {
        siz[x]=1;  
        for(int i=head[x];i;i=next[i])
        {  
            int y=ver[i];  
            dfs(y);  
            siz[x]+=siz[y];  
        }  
        if(!head[x]) f[x]=1; 
        if(head[x]) 
            for(int i=head[x];i;i=next[i])
                { int y=ver[i];f[x]=max(f[x],min(1.0*siz[y]/(siz[x]-1),f[y])); }
        if(siz[x]>k) ans=max(ans,f[x]);
    }  
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=2;i<=n;i++)
        {
            int a;scanf("%d",&a);
            add(a,i);
        }
        dfs(1);  
        printf("%.8lf
    ",ans); 
        return 0;
    } 
  • 相关阅读:
    必须为接口 System.Collections.IComparer 实现
    C#编写的windows程序随系统启动的问题
    ReportViewer导出Excel的问题
    英语听力的技巧
    Windows中无法删除文件的解决办法
    RDLC/RDL 动态报表
    Only export to PDF format from ReportViewer addin
    提高ASP.Net网站性能
    关于Spring 国际化 No message found under code 的解决方案
    Axis2中使用WSAddressing协议
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6166295.html
Copyright © 2011-2022 走看看