[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];
 8 bool safe[N]={0};
 9 std::vector<int> c[N];
10 struct Vertex {
11     int id,depth;
12     bool operator > (const Vertex &x) const {
13         return this->depth>x.depth;
14     }
15 };
16 Vertex v[N];
17 void dfs(const int x,const int depth) {
18     v[x].depth=depth;
19     for(unsigned int i=0;i<c[x].size();i++) dfs(c[x][i],depth+1);
20 }
21 void update(const int x) {
22     safe[p[x]]=safe[p[p[x]]]=true;
23     for(unsigned int i=0;i<c[p[x]].size();i++) safe[c[p[x]][i]]=true;
24     for(unsigned int i=0;i<c[x].size();i++) {
25         safe[c[x][i]]=true;
26         for(unsigned int j=0;j<c[c[x][i]].size();j++) {
27             safe[c[c[x][i]][j]]=true;
28         }
29     }
30 }
31 int main() {
32     int n;
33     scanf("%d",&n);
34     p[1]=1;
35     v[1].id=1;
36     for(int i=2;i<=n;i++) {
37         v[i].id=i;
38         scanf("%d",&p[i]);
39         c[p[i]].push_back(i);
40     }
41     dfs(1,0);
42     std::sort(&v[1],&v[n+1],std::greater<Vertex>());
43     int ans=0;
44     for(int i=1;i<=n;i++) {
45         if(safe[v[i].id]) continue;
46         update(p[p[v[i].id]]);
47         ans++;
48     }
49     printf("%d\n",ans);
50     return 0;
51 }
时间: 2024-08-29 02:28:22

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

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

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

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

[HNOI 2003]消防局的设立

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