[HNOI2003]消防局的设立

题目描述

2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地。起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构。如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d。

由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局。消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾。

你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在发生火灾时,消防队有能力及时扑灭火灾。

输入输出格式

输入格式:

输入文件名为input.txt。

输入文件的第一行为n (n<=1000),表示火星上基地的数目。接下来的n-1行每行有一个正整数,其中文件第i行的正整数为a[i],表示从编号为i的基地到编号为a[i]的基地之间有一条道路,为了更加简洁的描述树状结构的基地群,有a[i]<i。

输出格式:

输出文件名为output.txt

输出文件仅有一个正整数,表示至少要设立多少个消防局才有能力及时扑灭任何基地发生的火灾。

输入输出样例

输入样例#1:

6

1

2

3

4

5

输出样例#1:

2

Solution

这道题本来应该是考贪心的,但由于距离为2,所以树形dp也可以做

本篇主要讲贪心

首先,看到题目中的这句话

每个消防局有能力扑灭与它距离不超过2的基地的火灾。

这要求我们至少在底层的叶子结点一定要有消防局去覆盖它,这个时候有几个选择

  1. 自己本身
  2. 父亲节点
  3. 兄弟节点
  4. 祖父节点

很显然,前三种情况都可以被最后一种情况包括,即选择最后一种策略不会更劣,那么我们确定了贪心思路:如果我们确定了一个节点需要被覆盖,那么在它的祖父节点设立消防局就可以了

那么现在问题就是怎么找出那些需要被覆盖的节点?

我们用一个数组dis[i]表示i节点与离i最近的消防局之间的距离

初始值因为没有设立消防局,所以设为无限大

那么我们按深度从大到小排一遍序就可以了,如果当前dis[i]>2,就在祖父节点那里设立消防局

至于dis[i],可以一边做一边更新

Code

#include<bits/stdc++.h>
#define in(i) (i=read())
#define rg register
#define il extern inline
using namespace std; const int N=1e3+10; int read() {
int ans=0,f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') ans=ans*10+(i^48),i=getchar();
return ans*f;
} int n,ans;
int dep[N],dis[N],id[N],f[N];
bool cmp(int a,int b) {return dep[a]>dep[b];}
int main()
{
in(n); id[1]=1,dis[1]=dis[0]=N;
for(rg int i=2;i<=n;i++) {
in(f[i]); dep[i]=dep[f[i]]+1;//保证f[i]<i
id[i]=i,dis[i]=N;
}
sort(id+1,id+1+n,cmp);
for(rg int i=1;i<=n;i++) {
int u=id[i],v=f[u],gf=f[v];
dis[u]=min(dis[u],min(dis[v]+1,dis[gf]+2));
if(dis[u]>2) {
dis[gf]=0,ans++;
dis[f[gf]]=min(dis[f[gf]],1),dis[f[f[gf]]]=min(dis[f[f[gf]]],2);
}
}
cout<<ans<<endl;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

[HNOI2003]消防局的设立 (贪心)的更多相关文章

  1. BZOJ 1217: [HNOI2003]消防局的设立( 贪心 )

    一个简单的贪心, 我们只要考虑2个消防局设立的距离为5时是最好的, 因为利用最充分. 就dfs一遍, 再对根处理一下就可以了. 这道题应该是SGU某道题的简化版...这道题距离只有2, 树型dp应该也 ...

  2. [luogu]P2279 [HNOI2003]消防局的设立[贪心]

    [luogu]P2279 [HNOI2003]消防局的设立 题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两 ...

  3. P2279 [HNOI2003]消防局的设立 贪心or树形dp

    题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...

  4. luogu2279_[HNOI2003]消防局的设立 贪心

    传送门 不需要树形dp 关于深度排序 当前节点到最近的消防局(f[u])>2时要建新的与u的上面(v)的上面(w) 同时w的上面和上面的上面也要更新f值 #include <bits/st ...

  5. Luogu 2279 [HNOI2003]消防局的设立 - 贪心

    Description 给定一棵树形图, 建若干个消防站, 消防站能够覆盖到距离不超过2的点, 求最少需要建几个消防站才能覆盖所有点 Solution 从深度最深的点开始, 在它的爷爷节点上建, 每建 ...

  6. P2279 [HNOI2003]消防局的设立

    P2279 [HNOI2003]消防局的设立考场上想出了贪心策略,但是处理细节时有点问题,gg了.从(当前深度最大的节点)叶子节点往上跳k个,在这里设消防局,并从消防局遍历k个距离,标记上. #inc ...

  7. BZOJ1217: [HNOI2003]消防局的设立

    BZOJ1217: [HNOI2003]消防局的设立 Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地. 起初为了节约材料,人类只修建了n-1条道路来连接这些基地 ...

  8. 【BZOJ1217】[HNOI2003]消防局的设立 树形DP

    [BZOJ1217][HNOI2003]消防局的设立 Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地, ...

  9. 【洛谷P2279】[HNOI2003]消防局的设立

    消防局的设立 题目链接 贪心:每次取出深度最大的节点,若没有被覆盖到,要想覆盖它, 最优的做法显然是将它的爷爷设为消防局 (因为该节点深度为最大,选兄弟.父亲所覆盖的节点,选了爷爷后都能够覆盖) 用优 ...

随机推荐

  1. go学习笔记-Data类型(Arrays, Slices and Maps)

    Data类型(Arrays, Slices and Maps) array array就是数组,定义方式如下: var arr [n]type 在[n]type中,n表示数组的长度,type表示存储元 ...

  2. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  3. Spark 实践

    1.1 避免使用 GroupByKey   让我们看一下使用两种不同的方式去计算单词的个数,第一种方式使用 reduceByKey, 另外一种方式使用 groupByKey: val words = ...

  4. ORB-SLAM 代码笔记(四)tracking代码结构

    首先要清楚ORB-SLAM视觉跟踪的原理,然后对tracking.cc中的函数逐个讲解 代码的前面部分是从配置文件中读取校准好的相机参数(内参和畸变参数,以及双目的深度测量设定),并且加载ORB特征点 ...

  5. 实用脚本 2 -- Linux下定时执行脚本

    今天学习Linux下定时执行脚本,看到一篇讲解比较好的文章,特此拿来分享. 原文链接:http://www.blogjava.net/decode360/archive/2009/09/18/2877 ...

  6. LeetCode题目解答

    LeetCode题目解答——Easy部分 Posted on 2014 年 11 月 3 日 by 四火 [Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复 ...

  7. 教你用Bootstrap开发漂亮的前端界面

    Bootstrap介绍: Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目. Bootstrap的特点: 一.预处理脚本:虽然可以直 ...

  8. linux ----- Vim进入和退出命令

    Vim进入和退出命令     本来不想写任何关于vim的文章的,无奈我今天又忘记怎么退出vim了,常用命令是ESC,然后:wq(保存并退出),:q!(不保存并强制退出),i进入vim模式.另外还有其它 ...

  9. OpenCV实现SIFT图像拼接源代码

    OpenCV实现SIFT和KDtree和RANSAC图像拼接源代码,此源代码由Opencv2.4.13.6和VC++实现,代码本人已经调试过,完美运行,效果如附图.Opencv2.4.13.6下载地址 ...

  10. php解析二维码

    第一种方法: 安装PHP扩展 php-zbarcode之前需要先安装ImageMagick.zbar 第二种方法: 不需要那么麻烦,直接使用PHP的第三方类库 下载地址:https://github. ...