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

[luogu]P2279

[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



由于最大消防距离为定值,于是我们可以考虑贪心,每次选择深度最深的一个,在其爷爷处设立一个消防站,并以其爷爷为中心进行dfs,将长度为二的点都打上标记,打上标记将不再处理。

代码(练一下STL):

 1 //2017.11.6
 2 //greedy
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<queue>
 8 using namespace std;
 9 inline int read();
10 namespace lys{
11     const int N = 1e3 + 7 ;
12     struct egde{
13         int to;
14         int next;
15     }e[N*3];
16     struct DEEP{
17         int node,deep;
18         bool operator < (const DEEP &a) const{
19             return a.deep>deep;
20         }
21     };
22     priority_queue<DEEP> q;
23     bool used[N];
24     int pre[N],fa[N];
25     int n,cnt;
26     void add(int x,int y){
27         e[++cnt].to=y;e[cnt].next=pre[x];pre[x]=cnt;
28         e[++cnt].to=x;e[cnt].next=pre[y];pre[y]=cnt;
29     }
30     void dfs(int node,int deep){
31         q.push((DEEP){node,deep});
32         int i,v;
33         for(i=pre[node];i;i=e[i].next){
34             v=e[i].to;
35             if(v==fa[node]) continue ;
36             fa[v]=node;
37             dfs(v,deep+1);
38         }
39     }
40     void dfs1(int node,int deep){
41         if(deep>2) return ;
42         int i,v;
43         used[node]=true ;
44         for(i=pre[node];i;i=e[i].next){
45             v=e[i].to; dfs1(v,deep+1);
46         }
47     }
48     int main(){
49         int u,i;
50         n=read();
51         for(i=1;i<n;i++){
52             u=read(); add(u,i+1);
53         }
54         dfs(1,1);
55         cnt=0;
56         while(!q.empty()){
57             DEEP x=q.top();q.pop();
58             if(used[x.node]) continue ;
59             if(fa[fa[x.node]]) dfs1(fa[fa[x.node]],0);
60             else dfs1(1,0);
61             cnt++;
62         }
63         printf("%d\n",cnt);
64         return 0;
65     }
66 }
67 int main(){
68     lys::main();
69     return 0;
70 }
71 inline int read(){
72     int kk=0,ff=1;
73     char c=getchar();
74     while(c<‘0‘||c>‘9‘){
75         if(c==‘-‘) ff=-1;
76         c=getchar();
77     }
78     while(c>=‘0‘&&c<=‘9‘) kk=kk*10+c-‘0‘,c=getchar();
79     return kk*ff;
80 }
时间: 2024-11-09 03:59:54

[luogu]P2279 [HNOI2003]消防局的设立[贪心]的相关文章

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

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

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

题目描述 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的基地的火灾.你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在

[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];

BZOJ 1217 [HNOI2003]消防局的设立

题解:贪心,每次选深度最大的未被覆盖节点,在他的2级祖先处放一个 不会DP做法QWQ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100009; int n; int ans=0; int cntedge; int head[maxn]; int to[maxn<<1],n

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

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

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层,表示自己不一定被覆盖,但是孙子一定全部被覆盖 所谓向上覆

[HNOI 2003]消防局的设立

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