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

时间:2022-05-07
本文章向大家介绍CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

[编程题] 黑白树

时间限制: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

题目链接:https://www.nowcoder.com/question/next?pid=5599304&qid=105269&tid=8919747

分析: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 }