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

Description

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

Input

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

Output

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

Sample Input

6
1
2
3
4
5

Sample Output

2


论状态设计之巧妙

 1 /**************************************************************
 2     Problem: 1217
 3     User: ZYBGMZL
 4     Language: C++
 5     Result: Accepted
 6     Time:0 ms
 7     Memory:1312 kb
 8 ****************************************************************/
 9
10 #include<cstdio>
11 #include<cstring>
12 #include<iostream>
13 using namespace std;
14 #define inf 0x3f3f3f3f
15
16 struct Edge{
17     int to,nxt;
18     Edge(int to=0,int nxt=0):
19         to(to),nxt(nxt){}
20 };
21
22 const int maxn=1005;
23
24 int n,cnt=0,ans=0,f[maxn],head[maxn];
25 Edge E[maxn<<1];
26
27 inline void a_ed(int from,int to){
28     E[++cnt]=Edge(to,head[from]);  head[from]=cnt;
29     E[++cnt]=Edge(from,head[to]);  head[to]=cnt;
30 }
31
32 void dfs(int no,int fa){
33     int mx=-inf,mi=inf;
34     for(int e=head[no];e;e=E[e].nxt){
35         int nt=E[e].to;  if(nt==fa)  continue;
36         dfs(nt,no);
37         mx=max(mx,f[nt]);  mi=min(mi,f[nt]);
38     }
39     if(mx+mi<=3)  f[no]=mi+1;
40     else  f[no]=mx+1;
41     if(mx==-inf)  f[no]=3;
42     if(f[no]==5){
43         f[no]=0;
44         ans++;
45     }
46     if(f[no]>=3&&fa==-1)  ans++;
47 }
48
49 int main(){
50     scanf("%d",&n);
51     for(int i=2,to;i<=n;i++){
52         scanf("%d",&to);
53         a_ed(i,to);
54     }
55     dfs(1,-1);
56     printf("%d\n",ans);
57     return 0;
58 }
时间: 2024-10-13 21:01:05

bzoj1217: [HNOI2003]消防局的设立 [树形dp]的相关文章

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

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

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

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

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

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

[hdu3586]Information Disturbing树形dp+二分

题意:给出一棵带权无向树,以及给定节点1,总约束为$m$,找出切断与所有叶子节点联系每条边所需要的最小价值约束. 解题关键:二分答案,转化为判定性问题,然后用树形dp验证答案即可. dp数组需要开到ll,如果用设inf的解法. 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e6+7; 5 const int inf=0x3f3f3f3f; 6 struct e