其他分享
首页 > 其他分享> > [树形dp]

[树形dp]

作者:互联网

链接:https://ac.nowcoder.com/acm/problem/13249
来源:牛客网
题目描述

一棵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变黑
输出描述:
一个数表示最少操作次数
示例1 输入
4
1
2
1
1 2 2 1
输出
3
题意:给出一棵树,根节点编号为1,每个节点有一个权值ai表示从该节点向上距离不超过ai的点都可以被染色,求要使所有点被染色需要的最少操作次数
题解:容易想到dfs到叶子节点,叶子节点必须染色,然后在叶子结点以上被染过的点中找能染到的最小深度,以此向上染色操作次数最少,具体实现过程:递归地用dp[u]表示该节点或者该节点以下节点能染到的
最小深度,在已经被染色的点的尽头,也就是第一个未被染色的点A处ans+1,同时更新染色尽头为dp[A]即可,这里使用了数组pos记录染色尽头以便更新答案
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 //#define io_test
10 #define debug(x) cout<<x<<"####"<<endl;
11 typedef long long ll;
12 int rod[100005];
13 const int inf=0x3f3f3f3f;
14 struct edge{
15     int y;
16     int nex;
17 }e[100005];
18 int head[100005],cnt,dep[100005],dp[100005],pos[100005];
19 void adde(int x1,int y1){
20     e[cnt].y=y1;
21     e[cnt].nex=head[x1];
22     head[x1]=cnt++;
23 }
24 int cnt0=0;
25 void dfs(int u,int pre){
26     dep[u]=dep[pre]+1;
27     dp[u]=dep[u]-rod[u]+1;
28     pos[u]=inf;
29     for(int i=head[u];i!=-1;i=e[i].nex){
30         int v=e[i].y;
31         dfs(v,u);
32         dp[u]=min(dp[u],dp[v]);
33         pos[u]=min(pos[u],pos[v]);
34     }
35     if(pos[u]>dep[u]){
36         cnt0++;
37         pos[u]=dp[u];
38     }
39 }
40 int main()
41 {
42 #ifdef io_test
43     freopen("in.txt","r",stdin);
44     freopen("out.txt","w",stdout);
45 #endif // io_test
46     int n;
47     scanf("%d",&n);
48     memset(head,-1,sizeof(head));
49     for(int i=2;i<=n;i++){
50         int a;
51         scanf("%d",&a);
52         adde(a,i);
53     }
54     for(int i=1;i<=n;i++)scanf("%d",&rod[i]);
55     dep[0]=1;
56     dfs(1,0);
57     printf("%d\n",cnt0);
58     return 0;
59 }
View Code

 



标签:变黑,染色,树形,操作,include,节点,dp
来源: https://www.cnblogs.com/MekakuCityActor/p/10682949.html