基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 收藏
 取消关注
夹克老爷逢三抽一之后,由于采用了新师爷的策略,乡民们叫苦不堪,开始组织起来暴力抗租。
夹克老爷很愤怒,他决定派家丁常驻村中进行镇压。

诺德县 有N个村庄,编号0 至 N-1,这些村庄之间用N - 1条道路连接起来。

家丁都是经过系统训练的暴力机器,每名家丁可以被派驻在一个村庄,并镇压当前村庄以及距离该村庄不超过K段道路的村庄。
夹克老爷一贯奉行最小成本最大利润的原则,请问要实现对全部村庄的武力控制,夹克老爷需要派出最少多少名家丁?


Input
第1行:2个数N, K中间用空格分隔(1<= N <= 100000, 0 <= K <= N)。
之后N-1行:每行2个数S, E中间用空格分隔,表示编号为S的村庄同编号为E的村庄之间有道路相连。(0 <= S, E < N)。
Output
输出一个数说明要实现对全部村庄的武力控制,夹克老爷需要派出最少多少名家丁?
Input示例
4 1
0 1
0 2
0 3
Output示例
1

官方题解:树形DP,贪心思想,从叶子节点向上,能不放就不放,到了k长就放一个。

后序遍历,记录不同子树上传的状态,子树状态记录为该子树可以向上管理的(缺少的用负数)

可能A子树放置的家丁可以把B子树的村庄全部覆盖,这样就可以节约家丁数了。

min_length = min(dp[child])

max_length = max(dp[child])

if(min_length <= -K) {

    ++result;

    dp[cur_idx] = K;   //子树需要暴力支援深度达到K了,必须在当前位置放置一个家丁,并向上提供K的暴力输出

} else if(max_length + min_length > 0) {

    dp[cur_idx] = max_child - 1;      //有一个子树放置的家丁能够把全部其他需要镇压的村庄都覆盖

} else {

    dp[cur_idx] = min_child - 1;      //继续向上级要求暴力支持

}



最后如果root的状态小于0要额外多放一个。

这个题目真的挺好玩的,把这n个村庄n-1个连接想象成是一个树,然后记录每一个节点缺少的级别,当到达了k个级别的时候就要加上一个家丁,此时这个节点缺少的级别是正的k,因为它要开始照顾到它的兄弟子树了。

手动扩栈扩栈也是头一次。。。

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; #define inf 0x3f3f3f3f int res;
int n, k;
int s, e;
int used[100050];
int dp[100050];
vector<int>node[100050]; void dfs(int x)
{
used[x] = 1;
int minn = inf;
int maxn = -inf;
int size = node[x].size(); int i;
for (i = 0; i < size; i++)
{
int temp = node[x][i];
if (used[temp] == 0)
{
dfs(temp);
minn = min(minn, dp[temp]);
maxn = max(maxn, dp[temp]);
}
}
if (minn == inf)
{
dp[x] = -1;
}
else if(minn<=-k)
{
res++;
dp[x] = k;
}
else if (maxn + minn > 0)
{
dp[x] = maxn - 1;
}
else
{
dp[x] = minn - 1;
}
used[x] = 0;
} int main()
{
//freopen("i.txt", "r", stdin);
//freopen("o.txt", "w", stdout); int i;
scanf("%d%d", &n, &k); for (i = 1; i <= n - 1; i++)
{
scanf("%d%d", &s, &e);
s++;
e++;
node[s].push_back(e);
node[e].push_back(s);
}
if (k == 0)
{
printf("%d", n);
return 0;
}
dfs(1); if (dp[1] < 0)
{
res++;
}
printf("%d", res);
//system("pause");
return 0;
}

51nod 1378:夹克老爷的愤怒 很好玩的一道树状dp的更多相关文章

  1. 51nod 1378 夹克老爷的愤怒(树型dp+贪心)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1378 题意: 思路:要想放得少,尽量放在叶子节点处,叶子节点处点比较多. ...

  2. 51Nod 1378 夹克老爷的愤怒

    Description 一棵树,可以进行染色,被染色的点可以控制与它距离不超过 \(k\) 的所有点,问控制整棵树最少需要染几个点. Sol 贪心. 记录一下最深的未染色点和最浅的染色点,判断一下能否 ...

  3. 51nod 1380"夹克老爷的逢三抽一"(贪心+set)

    传送门 •参考资料 [1]:51Nod-1380-夹克老爷的逢三抽一 •题意 从长度为 n 的数组中抽取 $\frac{n}{3}$ 个不相邻的值使得加和最大(首尾也不能同时取) •题解 贪心选择当前 ...

  4. 51nod 1276:岛屿的数量 很好玩的题目

    1276 岛屿的数量 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  取消关注 有N个岛连在一起形成了一个大的岛屿,如果海平 ...

  5. 51Nod 1380 夹克老爷的逢三抽一

    Description 一开始有一个环,可以选择删除一个元素获得他的权值,同时删除与它相邻的两个元素,其他元素重新形成环,问能获得的最大价值. Sol 堆+贪心. 一开始从堆中加入所有元素,然后取出一 ...

  6. 51nod 1380:夹克老爷的逢三抽一

    1380 夹克老爷的逢三抽一 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题  收藏  取消关注 又到了诺德县的百姓孝敬夹克大老爷的日子,带着数量不等的铜板的村民 ...

  7. 51nod 1276 1276 岛屿的数量 (很好玩的题目

    题意: 有N个岛连在一起形成了一个大的岛屿,如果海平面上升超过某些岛的高度时,则这个岛会被淹没.原本的大岛屿则会分为多个小岛屿,如果海平面一直上升,则所有岛都会被淹没在水下. 给出N个岛的高度.然后有 ...

  8. The Go tools for Windows + Assembler很好玩

    我想用python做个tiny BASIC编译器.赋值和加减乘除,IF和FOR. 语法分析python有ply包,用ply.lex和ply.yacc做个计算器很简单,我已经做了. 做个解释器应该也不难 ...

  9. Ansible好像很好玩的样子哟

    这个比SALTSTACK轻量,,不知道速度如何..... 参考文档: http://linux.cn/article-4215-1.html wget http://download.fedorapr ...

随机推荐

  1. JAVA 常用包

    JAVA是以包的形式进行语言结构组织的. 引入这些包的关键词就是 import 下面说说 JAVA常用包有下面的几个 1. java.lang 这个是默认引入的,也是一个最基础的包.其中lang不是中 ...

  2. navicat12破解详细教程

    以管理员身份运行此注册机: 运行注册机 打开注册机后,1) Patch勾选Backup.Host和Navicat v12,然后点击Patch按钮: 默认勾选 找到Navicat Premium 12安 ...

  3. Codeforces #617 (Div. 3) C. Yet Another Walking Robot

    There is a robot on a coordinate plane. Initially, the robot is located at the point (0,0)(0,0) . It ...

  4. Linux centos VMware Nginx防盗链、Nginx访问控制、Nginx解析php相关配置、Nginx代理

    一.Nginx防盗链 配置如下,可以和上面的配置结合起来 location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|x ...

  5. Linux centosVMware Nginx安装、 默认虚拟主机、Nginx用户认证、Nginx域名重定向

    一. Nginx安装 cd /usr/local/src wget http://nginx.org/download/nginx-1.12.1.tar.gz 版本在http://nginx.org/ ...

  6. python学习 —— 使用QRCode包生成二维码

    我使用的是python3,最简单的方法就是使用QRCode,如果没有安装QRCode package,那么可以使用下面命令进行安装: pip3 install QRCode 然后,测试一下: from ...

  7. Python正则表达式就是这么简单【新手必学】

    一前言本篇文章带大家快速入门正则表达式的使用,正则表达式的规则不仅适用python语言,基本大多数编程语言都适用,在日常使用中极为广泛,读者们有必要学好正则表达式.看完这篇文章,读者们要理解什么是正则 ...

  8. Centos7 nginx的目录结构与nginx主配置文件解析

    一.nginx的目录结构 [root@node nginx_116]# ls client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp ...

  9. 图论初步<蒟蒻专属文章>

    前言:    图论乃noip之重要知识点,但有点难理解 本人因此吃过不少亏 因为本人实在太弱,所以此篇乃正宗<蒟蒻专属文章> 正文:(本文仅介绍图论中的重点.难点,其余部分略将或不讲) 图 ...

  10. Java 在Excel单元格中应用一种/多种字体样式

    在Excel表格中,设置单元格字体样式时,可以对单元格内的所有字符应用同一样式,即获取指定单元,应用样式即可:另外也可以对单元格内的不同字符内容应用不同字体样式,即获取单元格中的字符位置,应用样式:本 ...