[HNOI2003]消防局的设立 (贪心)
[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的基地的火灾。
这要求我们至少在底层的叶子结点一定要有消防局去覆盖它,这个时候有几个选择
- 自己本身
- 父亲节点
- 兄弟节点
- 祖父节点
很显然,前三种情况都可以被最后一种情况包括,即选择最后一种策略不会更劣,那么我们确定了贪心思路:如果我们确定了一个节点需要被覆盖,那么在它的祖父节点设立消防局就可以了
那么现在问题就是怎么找出那些需要被覆盖的节点?
我们用一个数组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]消防局的设立 (贪心)的更多相关文章
- BZOJ 1217: [HNOI2003]消防局的设立( 贪心 )
一个简单的贪心, 我们只要考虑2个消防局设立的距离为5时是最好的, 因为利用最充分. 就dfs一遍, 再对根处理一下就可以了. 这道题应该是SGU某道题的简化版...这道题距离只有2, 树型dp应该也 ...
- [luogu]P2279 [HNOI2003]消防局的设立[贪心]
[luogu]P2279 [HNOI2003]消防局的设立 题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两 ...
- P2279 [HNOI2003]消防局的设立 贪心or树形dp
题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...
- luogu2279_[HNOI2003]消防局的设立 贪心
传送门 不需要树形dp 关于深度排序 当前节点到最近的消防局(f[u])>2时要建新的与u的上面(v)的上面(w) 同时w的上面和上面的上面也要更新f值 #include <bits/st ...
- Luogu 2279 [HNOI2003]消防局的设立 - 贪心
Description 给定一棵树形图, 建若干个消防站, 消防站能够覆盖到距离不超过2的点, 求最少需要建几个消防站才能覆盖所有点 Solution 从深度最深的点开始, 在它的爷爷节点上建, 每建 ...
- P2279 [HNOI2003]消防局的设立
P2279 [HNOI2003]消防局的设立考场上想出了贪心策略,但是处理细节时有点问题,gg了.从(当前深度最大的节点)叶子节点往上跳k个,在这里设消防局,并从消防局遍历k个距离,标记上. #inc ...
- BZOJ1217: [HNOI2003]消防局的设立
BZOJ1217: [HNOI2003]消防局的设立 Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地. 起初为了节约材料,人类只修建了n-1条道路来连接这些基地 ...
- 【BZOJ1217】[HNOI2003]消防局的设立 树形DP
[BZOJ1217][HNOI2003]消防局的设立 Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地, ...
- 【洛谷P2279】[HNOI2003]消防局的设立
消防局的设立 题目链接 贪心:每次取出深度最大的节点,若没有被覆盖到,要想覆盖它, 最优的做法显然是将它的爷爷设为消防局 (因为该节点深度为最大,选兄弟.父亲所覆盖的节点,选了爷爷后都能够覆盖) 用优 ...
随机推荐
- tail命令使用
1.tail命令 命令的主要用途是将指定的文件的最后部分输出到终端,如果该文件有更新,tail会自己主动刷新. 2.tail语法 tail [ -f ] [ -c Number | -n Number ...
- 动态规划----FatMouse’s Speed(HDU 1160)
参考:https://blog.csdn.net/u012655441/article/details/64920825 https://blog.csdn.net/wy19910326/articl ...
- [JSOI2007] 建筑抢修 (贪心 + 优先队列)
小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会 ...
- 【UE4】二十六、Look at camera 蓝图
如图,把BP_Cube替换为你需要的对象(如3DUI等)即可.
- JAVA大作业汇总3
JAVA大作业3 代码 ``` package thegreatwork; import java.util.; import java.io.; /Board.java 目的:里面有一些关于如何移动 ...
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(四):安装MySQL数据库
基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(二):Apache安装和配置
基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...
- DSP28335的XINTF操作SRAM实验
1. 本次使用三兄弟的XDS28335开发板,研究一下XINTF操作SRAM的代码.哈弗结构,奇怪,DSP28335是哈弗结构,那么数据和程序空间应该独立的,为啥书上说采用统一的寻址方式?估计只是读写 ...
- Unity3d创建物体,寻找物体,加载物体,添加脚本
GetCreateObject: using UnityEngine; public class GetCreateObject : MonoBehaviour { GameObject emptyG ...
- PHP二维数组按某个键值排序
$data=Array( [0] => Array ( [id] => 2 [user_id] => 14 ...