• uva12186 Another Crisis


    题目大意:

    世界危机发生了,工人们请求加薪。一个老板和n个员工组成树状结构,每个员工都有自己的唯一上司,Boss的编号为0,员工1~n,工人们打算签署一个志愿书给老板,但无法跨级,当一个中级员工(非是工人的员工)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司,问:要让Boss收到请愿书至少需要多少个工人签字

    /*
        设d[u]表示让u给上级发信至少需要多少个工人。假设u有k个子节点,则至少需要C=(kT-1)100+1的直接下属发信才行。把所有的子节点的d值从小到大排序,前C个加起来即可。时间复杂度:O(nlogn)
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 100010
    int n,t,num,head[maxn];
    struct node{
        int to,pre;
    }e[maxn];
    void Insert(int from,int to){
        e[++num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    int dfs(int now){
        int tmp[maxn],cnt=0,res=0;
        bool flag=0;//判断是否是叶子节点 
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            tmp[++cnt]=dfs(to);
            flag=1;
        }
        if(!flag)return 1;
        sort(tmp+1,tmp+cnt+1);
        int limit=(cnt*t-1)/100+1;
        for(int i=1;i<=limit;i++)res+=tmp[i];
        return res;
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        while(1){
            scanf("%d%d",&n,&t);
            memset(e,0,sizeof(e));
            memset(head,0,sizeof(head));
            num=0;
            if(n==0&&t==0)return 0;
            int x;
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                Insert(x,i);
            }
            printf("%d
    ",dfs(0));
        }
    }
  • 相关阅读:
    Java输出文件到本地(输出流)
    Java 工厂设计模式
    实际工作与JAVA面试题
    JAVA 转义字符串中的特殊字符
    Oracle工作笔记
    JS验证表单中TEXT文本框中是否含有非法字符
    JAVA 解析TXT文本
    表单异步提交数据
    rem.js(2)
    rem.js(1)
  • 原文地址:https://www.cnblogs.com/thmyl/p/7416263.html
Copyright © 2020-2023  润新知