[HNOI 2003]消防局的设立

Description

2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地。起初为了节约材料,人类只修建了n-1条道路来

连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构。如果基地A到

基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d。由于火星上非常干燥,经常引发火灾,人类决定

在火星上修建若干个消防局。消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾。

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

Input

第一行为n,表示火星上基地的数目。N<=1000

接下来的n-1行每行有一个正整数,其中文件第i行的正整数为a[i],表示从编号为i的基地到编号为a[i]的基地之间有一条道路,

为了更加简洁的描述树状结构的基地群,有a[i] < i

Output

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

Sample Input

6
1
2
3
4
5

Sample Output

2

题解

[UVa 1267]Network思路很类似,选最深的未盖点的$2$级祖先覆盖就好了。

 1 //It is made by Awson on 2017.11.3
 2 #include <set>
 3 #include <map>
 4 #include <ctime>
 5 #include <cmath>
 6 #include <queue>
 7 #include <stack>
 8 #include <vector>
 9 #include <cstdio>
10 #include <string>
11 #include <cstring>
12 #include <cstdlib>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define sqr(x) ((x)*(x))
19 using namespace std;
20 const int N = 1000;
21
22 int n, a;
23 struct tt {
24     int to, next;
25 }edge[(N<<1)+5];
26 int path[N+5], top;
27 int fa[N+5];
28 struct ss {
29     int u, a;
30     bool operator < (const ss &b) const {
31     return a > b.a;
32     }
33 }q[N+5];
34 bool cover[N+5];
35
36 void dfs(int u, int father, int dep) {
37     q[u].u = u, q[u].a = dep, fa[u] = father;
38     for (int i = path[u]; i; i = edge[i].next)
39     if (edge[i].to != father) dfs(edge[i].to, u, dep+1);
40 }
41 void coverit(int u, int dep) {
42     cover[u] = 1; if (dep == 0) return;
43     for (int i = path[u]; i; i = edge[i].next)
44     coverit(edge[i].to, dep-1);
45 }
46 void add(int u, int v) {
47     edge[++top].to = v;
48     edge[top].next = path[u];
49     path[u] = top;
50 }
51 void work() {
52     scanf("%d", &n);
53     for (int i = 2; i <= n; i++) {
54     scanf("%d", &a); add(a, i); add(i, a);
55     }
56     dfs(1, 0, 1);
57     sort(q+1, q+1+n);
58     int ans = 0;
59     for (int i = 1; i <= n; i++) {
60     if (cover[q[i].u]) continue;
61     ans ++; int a = fa[fa[q[i].u]];
62     if (!a) break;
63     coverit(a, 2);
64     }
65     printf("%d\n", ans);
66 }
67 int main() {
68     work();
69     return 0;
70 }
时间: 2024-10-08 07:45:45

[HNOI 2003]消防局的设立的相关文章

BZOJ1217: [HNOI2003]消防局的设立

1217: [HNOI2003]消防局的设立 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 734  Solved: 405[Submit][Status][Discuss] Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构.如果基地A到基地B至少要经过d条道路的话,我们称基地A

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

[luogu]P2279 [HNOI2003]消防局的设立 题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构.如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d. 由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局.消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾. 你的任务是计算

P2279 [HNOI2003]消防局的设立

P2279 [HNOI2003]消防局的设立考场上想出了贪心策略,但是处理细节时有点问题,gg了.从(当前深度最大的节点)叶子节点往上跳k个,在这里设消防局,并从消防局遍历k个距离,标记上. 1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #incl

【贪心】P3942 将军令 &amp;&amp; P2279 消防局的设立

1.消防局的设立 题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构.如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d. 由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局.消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾. 你的任务是计算至少要修建多少个消防局才能够确保火星上所有

bzoj1217: [HNOI2003]消防局的设立 [树形dp]

Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构.如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d.由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局.消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾.你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在

bzoj 1217 [HNOI2003]消防局的设立 Label:图论

题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构.如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d. 由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局.消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾. 你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在发生火灾时

[HNOI2003]消防局的设立

OJ题号:BZOJ1217.洛谷2279 思路:贪心. 先DFS记录各个结点的深度,然后从深度大的结点贪心,如果当前结点不安全,就在它爷爷地方开消防局,同时更新上下二代的安全信息. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 #include<functional> 6 const int N=1001; 7 int p[N];

P2279 消防局的设立 (树形DP or 贪心)

(点击此处查看原题) 树形DP写法 看到这个题的要求,很容易相到这是一个树形DP的问题,但是dp数组应该如何设计并转移才是关键 dp[i][0]代表当前结点可以向上覆盖2层,自身一定被覆盖dp[i][1]代表当前结点可以向上覆盖1层,自身一定被覆盖dp[i][2]代表当前结点可以向上覆盖0层,自身一定被覆盖dp[i][3]代表当前结点可以向下覆盖1层,表示自己不一定被覆盖,但是儿子一定全部被覆盖dp[i][4]代表当前结点可以向下覆盖2层,表示自己不一定被覆盖,但是孙子一定全部被覆盖 所谓向上覆

BZOJ 1216 HNOI 2003 操作系统 堆

题目大意 给出一个CPU处理事件的规则,给出一些事件,问处理这些事件的顺序和结束时间. 思路 我们只需要维护一个堆来模拟他说的规则,之后按顺序输出就行了. CODE #define _CRT_SECURE_NO_WARNINGS #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 151