CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】

简介: [编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1。树上每个节点i对应一个值k[i]。每个点都有一个颜色,初始的时候所有点都是白色的。
[编程题] 黑白树

时间限制:1秒

空间限制:32768K

一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1。树上每个节点i对应一个值k[i]。每个点都有一个颜色,初始的时候所有点都是白色的。
你需要通过一系列操作使得最终每个点变成黑色。每次操作需要选择一个节点i,i必须是白色的,然后i到根的链上(包括节点i与根)所有与节点i距离小于k[i]的点都会变黑,已经是黑的点保持为黑。问最少使用几次操作能把整棵树变黑。
输入描述:
第一行一个整数n (1 ≤ n ≤ 10^5)
接下来n-1行,每行一个整数,依次为2号点到n号点父亲的编号。
最后一行n个整数为k[i] (1 ≤ k[i] ≤ 10^5)

样例解释:
对节点3操作,导致节点2与节点3变黑
对节点4操作,导致节点4变黑
对节点1操作,导致节点1变黑


输出描述:
一个数表示最少操作次数

输入例子:
4
1
2
1
1 2 2 1

输出例子:
3
分析:DFS深搜+暴力写法,可以参考一下的啦!
其实就是一个DFS递归啊,
子树全变黑的最优解:sum1,
在最优解sum1下最多还能向上延伸的点数,sum2,
sum3是,子树下不被选择的点作为备选的点,最多还能向上延伸的点数!
下面给出AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N =166666;
 4 typedef long long ll;
 5 vector<ll> T[N];
 6 ll n,a[N];
 7 struct Tree
 8 {
 9     ll ans;
10     ll maxn;
11     ll Gmaxn;
12 };
13 inline ll read()
14 {
15     ll x=0,f=1;
16     char ch=getchar();
17     while(ch<'0'||ch>'9')
18     {
19         if(ch=='-')
20             f=-1;
21         ch=getchar();
22     }
23     while(ch>='0'&&ch<='9')
24     {
25         x=x*10+ch-'0';
26         ch=getchar();
27     }
28     return x*f;
29 }
30 inline void write(ll x)
31 {
32     if(x<0)
33     {
34         putchar('-');
35         x=-x;
36     }
37     if(x>9)
38     {
39         write(x/10);
40     }
41     putchar(x%10+'0');
42 }
43 Tree DFS(ll xx,ll yy)
44 {
45     Tree ret={0,0,0};
46     ll sum1=0,sum2=-1,sum3=-1;
47     for(ll i=0;i<T[xx].size();i++)
48     {
49         ll to=T[xx][i];
50         if(to==yy)
51             continue;
52         ret=DFS(to,xx);
53         sum1+=ret.ans;
54         sum2=max(ret.maxn,sum2);
55         sum3=max(ret.Gmaxn,sum3);
56     }
57     if(sum2<=-1)
58     {
59         sum2=max(a[xx],sum3);
60         sum1+=1;
61     }
62     sum3=max(sum3,a[xx]);
63     ret.ans=sum1;
64     ret.maxn=sum2-1;
65     ret.Gmaxn=sum3-1;
66     return ret;
67 }
68 int main()
69 {
70     ll p;
71     n=read();
72     for(ll i=1;i<=n-1;i++)
73     {
74         p=read();
75         T[p].push_back(i+1);
76     }
77     for(ll i=1;i<=n;i++)
78     {
79         a[i]=read();
80         a[i]--;
81     }
82     write(DFS(1,0).ans);
83     return 0;
84 }

 

目录
相关文章
|
5月前
|
算法
【错题集-编程题】腐烂的苹果(多源 BFS + 最短路)
【错题集-编程题】腐烂的苹果(多源 BFS + 最短路)
|
3月前
【蓝桥杯】[递归]母牛的故事
蓝桥杯——[递归]母牛的故事
38 1
【蓝桥杯】[递归]母牛的故事
|
3月前
|
存储 定位技术
【天梯赛】L2-048 寻宝图 (DFS做法)
遇到一个非'0'字符(也就是'1'和 宝藏'2'到'9')就让ans++,同时将这个非'0'字符染色为'0',然后往四个方向(上、下、左、右)搜索,这里的目的是那一片岛屿(也就是那一片为'1'的部分)都染色为‘0’。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。为了判断有宝藏的岛屿,这里我开了一个全局变量f来判断这一片岛屿是否有宝藏(也就是有无字符'2'-'9'),当搜到字符'2'~'9'时就将f标记为1。在一行中输出 2 个整数,分别是岛屿的总数量和有宝藏的岛屿的数量。
43 5
|
5月前
|
存储
【错题集-编程题】组队竞赛(排序 + 贪心)
【错题集-编程题】组队竞赛(排序 + 贪心)
|
算法 Java Python
【算法模板】DFS秒杀模板—附练习题(阳光号启航)(一)
【算法模板】DFS秒杀模板—附练习题(阳光号启航)(一)
【算法模板】DFS秒杀模板—附练习题(阳光号启航)(一)
|
算法
算法竞赛题解:校门外的树
NOIP2005 普及组:校门外的树
232 0
|
人工智能 算法 C++
【每日算法Day 88】超越妹妹教你如何做这道排序题
【每日算法Day 88】超越妹妹教你如何做这道排序题
|
算法 程序员
【算法集训 | 暑期刷题营】8.2题---暴力递归之深搜
【算法集训 | 暑期刷题营】8.2题---暴力递归之深搜
【算法集训 | 暑期刷题营】8.2题---暴力递归之深搜
|
算法 程序员 C++
【算法集训 | 暑期刷题营】8.11题---回溯与剪枝
【算法集训 | 暑期刷题营】8.11题---回溯与剪枝
【算法集训 | 暑期刷题营】8.11题---回溯与剪枝
|
算法 编译器 C++
<<算法很美>>——(七)——DFS典题(二):数独游戏
<<算法很美>>——(七)——DFS典题(二):数独游戏
<<算法很美>>——(七)——DFS典题(二):数独游戏
下一篇
无影云桌面