UVAOJ 12186 Another Crisis (树形DP)

题意:

给出一个树状关系图。公司里仅仅有一个老板编号为0,其它人员从1開始编号。

除了老板,每一个人都有一个直接上司,没有下属的员工成为工人。

工人们想写一份加工资的请愿书,仅仅有当不少于员工的全部下属的T%人递交请愿书后,该员工才会将请愿书递交给他的直接上级。输出能递交到老板处,最少须要多少工人写请愿书

思路:

d(u)表示让u给上级发信最少须要多少个工人。如果u有k个子节点,则至少须要c = (k*T - 1) / 100 + 1 个直接下级发信给他才行。

把全部子节点的d从小到大排序,前c个和就是d(u)。而所求答案就是d(0)。

从枝叶向树根dp就可以,只是搜索的形式dp会更简单。就不须要再dfs预处理了

//	Accepted	C++	0.245
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e5+1e2;
int T;
int n;
int mdep;
int dp[N]; //此人给上级发信最少须要多少个最底层工人
vector<int> dep[N];
struct Edge
{
    int v;
    Edge(int _v=0) : v(_v) {};
};
vector <Edge> es[N];//每一个节点的儿子
void dfs_makedep(int u,int d) //统计每一个深度有哪些结点。从枝叶向根递推
{
    mdep=max(mdep,d);
    dep[d].push_back(u);
    for(int i=0;i<es[u].size();i++)
    {
        dfs_makedep(es[u][i].v,d+1);
    }
}
void ini()
{
    mdep=-1;
    memset(dp,0,sizeof(dp));
    for(int i=0;i<=n;i++)
    {
        es[i].clear();
        dep[i].clear();
    }
}

int main()
{
    while(scanf("%d%d",&n,&T),(T||n))
    {
        ini();
        for(int v=1;v<=n;v++)
        {
            int u;
            scanf("%d",&u);
            es[u].push_back(Edge(v));
        }
        dfs_makedep(0,0);
        for(int l=mdep;l>=0;l--)
            for(int i=0;i<dep[l].size();i++)
            {
                int u=dep[l][i];
                if(es[u].empty()) //border
                {
                    dp[u]=1;
                    continue;
                }
                vector<int>tmp;
                for(int j=0;j<es[u].size();j++)
                    tmp.push_back(dp[es[u][j].v]);
                sort(tmp.begin(),tmp.end());
                int c=(es[u].size()*T-1)/100  + 1;//小技巧
                for(int k=0;k<c;k++)
                    dp[u]+=tmp[k];
            }
        printf("%d\n",dp[0]);
    }
    return 0;
}
时间: 2024-11-05 22:40:12

UVAOJ 12186 Another Crisis (树形DP)的相关文章

uva 12186 Another Crisis 树形dp

// uva 12186 Another Crisis 树形dp // // 对于一个节点u,有k个子节点,则至少有c = (k * T - 1) / 100 + 1才能 // 发信,即c / k >= T / 100,则 c 的值为 k * T /100,上取整变成上式 // 将所有的子节点d从小到大排序,取前c个就是d[u]的值 // 紫书上的一题,之前看了好久好久,觉得挺好的,然而一直没做,今天就来 // 体验体验,挺好的一题,注意一下,如果一个节点是叶节点,直接return 1就好 //

UVA12186--- Another Crisis (树形dp)

Description Download as PDF A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries. The company has a strict hiera

UVa 12186 Another Crisis (DP)

题意:有一个老板和n个员工,除了老板每个员工都有唯一的上司,老板编号为0,员工们为1-n,工人(没有下属的员工),要交一份请愿书, 但是不能跨级,当一个不是工人的员工接受到直系下属不少于T%的签字时,自己也会签字,并交给上级,问你最少有多少工人签字,才能让老板收到请愿书. 析:题意比较简单,也好理解,很明显是一个动态规划的题目,d(u)表示u给上级要发信至少需要多少工人签字.假设u有k个结点,那么至少要 c = (kT-1)/100 + 1个工人,然后把每个结点排序,找出最少的工人即可,挺简单的

UVA 12186 Another Crisis(树形DP)

A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries. The company has a strict hierarchy, in which each employee

UVa12186:Another Crisis(树形DP)

一道简单的树形DP送给你. A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries. 数年以前,人们遭受了世界范围的经济危机.于是某司工人们要求涨薪.(我百度了一下,金融危机

uva 1220 - Party at Hali-Bula 【入门树形dp】

题目:uva 1220 - Party at Hali-Bula 题意:一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一 分析:分析发现是要求一个树的最大独立集.这里可以用树形dp解决. 定义dp[x][0]:表示在 i 点不选 i 点的以 x 为子树的最大独立集 而dp[x][1] 表示x到场的最大独立集 定义f [x][0]:表示以x为根且x点不选的子树是否唯一 ,f[x][1]表示以x为根且x选的子树是否唯

树形dp

树形dp,意思就是在树上的dp, 看了看紫书,讲了三个大点把,一个是树的最大独立集,另外一个是树的重心,最后一个是树的最长路径.给的三个例题,下面就从例题说起 第一个:工人的请愿书 uva 12186 这个题目给定一个公司的树状结构,每个员工都有唯一的一个直属上司,老板编号为0,员工1-n,只有下一级的工人请愿书不小于T%时,这个中级员工,才会签字传递给它的直属上司,问老板收到请愿书至少需要多少各个工人签字 用dp(u)表示u给上级发信至少需要多少工人,那么可以假设u有k个节点,所以需要c =

UVA 12186 Another Crisis

UVA 12186 Another Crisis:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=243&page=show_problem&problem=3338 题意:世界危机发生了,工人们请求加薪.一个老板和n个员工组成树状结构,每个员工都有自己的唯一上司,Boss的编号为0,员工1~n,工人们打算签署一个志愿书给老板,但无法跨级,当一个中级员工(非是工人的员

HDU-2196 Computer (树形DP)

最近在看树形DP,这题应该是树形DP的经典题了,写完以后还是有点感觉的.之后看了discuss可以用树分治来做,以后再试一试. 题目大意 找到带权树上离每个点的最远点.︿( ̄︶ ̄)︿ 题解: 对于每一个点的最远点,就是以这个点为根到所有叶子节点的最长距离.但是如果确定根的话,除了根节点外,只能找到每个节点(度数-1)个子树的最大值,剩下一个子树是该节点当前的父亲节点. 所以当前节点的最远点在当前节点子树的所有叶子节点以及父亲节点的最远点上(当父亲节点的最远点不在当前节点的子树上时), 如果父亲节