zoukankan      html  css  js  c++  java
  • 【UVa 12186】Another Crisis

    Link:

    Description

    给你n个员工和一个boss;
    这n个员工和boss之间的关系是一棵树;
    然后,现在最底层的叶子节点,想要向上级写信;
    每个叶子节点都会向上级写一封信;
    然而,每个中级人员,只有在它的下属中的百分之T以上的人都给它写信,它才会往上一级写信;
    问你boss收到信,最少需要多少个工人写信才够;

    Solution

    设dp[x]表示x往上写信,最少需要有几个工人写信才够;
    cnt[x]为x的儿子节点的个数;
    则在做dfs的时候,把儿子节点的dp值升序排,存在vector里面
    则每次在x的儿子节点中选择前ceil(T*0.01*cnt[x])个人把它们的DP值加起来,作为x的dp值;
    (ceil是向上取整)
    这样就是最小的了;
    对于叶子节点x,dp[x]=1

    NumberOf WA

    0

    Reviw

    那个vector不能是全局变量的。。。
    只能存在递归里;

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define Open() freopen("F:\rush.txt","r",stdin)
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define pb push_back
    
    const int N = 1e5;
    
    char s[N+10];
    int dp[N+10],n,t;
    vector <int> g[N+10];
    
    void dfs(int x){
        if (g[x].empty()){
            dp[x] = 1;
            return;
        }
        int len = g[x].size();
        vector <int> v;
        rep1(i,0,len-1){
            int y = g[x][i];
            dfs(y);
            v.pb(dp[y]);
        }
        sort(v.begin(),v.end());
        int num = ceil(1.0*t/100.0*len);
        dp[x] = 0;
        rep1(i,0,num-1) dp[x]+=v[i];
    }
    
    int main(){
        //Open();
        while (~scanf("%d%d",&n,&t)){
            if (n==0 && t==0) break;
            rep1(i,0,n) g[i].clear();
            rep1(i,1,n){
                int x;
                scanf("%d",&x);
                g[x].pb(i);
            }
            dfs(0);
            printf("%d
    ",dp[0]);
        }
        return 0;
    }
  • 相关阅读:
    URL中 # (hash)的含义
    哈弗曼树的理解和实现(Java)
    树、森林和二叉树的转换
    后序线索化二叉树(Java版)
    线索二叉树的理解和实现(Java)
    彻底理解线索二叉树
    链式二叉树的实现(Java)
    数和二叉树的基本概念和类型
    数据结构:广义表的实现(Java)
    正则表达式要转义的字符集
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626189.html
Copyright © 2011-2022 走看看