Codeforces 682C Alyona and the Tree (树上DFS+DP)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 682C Alyona and the Tree (树上DFS+DP)相关的知识,希望对你有一定的参考价值。
题目链接:http://codeforces.com/problemset/problem/682/C
题目大意:
取树上任意一个点v,若点v的子树中有一个点u使得dist(v,u)>a[u]那么称节点v是伤心的。
给你一个根为1的树,每个节点有一个权值a[i],每条边也有一个权值w,
现在让你删最少的结点,使得树上不存在伤心的点。
解题思路:
删除最少的点,我们可以反一下,变成找最多的点,使得这些点不伤心。
只要对这棵树进行DFS,同时记录路径长度dis,当到达某点u时,
若dis>a[u],那么要将u及u的子树删除,所以直接return,不再继续遍历。
注意,这里的dis是1~u的最长路径,所以当dis<0时使得dis=0,类似最大子段和的做法。
代码:
1 #include<bits/stdc++.h> 2 #define lc(a) (a<<1) 3 #define rc(a) (a<<1|1) 4 #define MID(a,b) ((a+b)>>1) 5 #define fin(name) freopen(name,"r",stdin) 6 #define fout(name) freopen(name,"w",stdout) 7 #define clr(arr,val) memset(arr,val,sizeof(arr)) 8 #define _for(i,start,end) for(int i=start;i<=end;i++) 9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); 10 using namespace std; 11 typedef long long LL; 12 const int N=2e5+5; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-10; 15 16 struct node{ 17 int to,w; 18 node(int to,int w):to(to),w(w){} 19 }; 20 21 int ans; 22 int a[N]; 23 vector<node>v[N]; 24 25 void dfs(int u,LL dis,int fa){ 26 if(dis>a[u]) return; //dis(v,u)>a[u]不符合 27 ans++; 28 for(int i=0;i<v[u].size();i++){ 29 node t=v[u][i]; 30 if(t.to==fa) continue; 31 dfs(t.to,max(0LL,dis+t.w),u);//dis<0则取0 32 } 33 } 34 35 int main(){ 36 FAST_IO; 37 int n; 38 cin>>n; 39 for(int i=1;i<=n;i++){ 40 cin>>a[i]; 41 } 42 for(int i=2;i<=n;i++){ 43 int to,w; 44 cin>>to>>w; 45 v[i].push_back(node(to,w)); 46 v[to].push_back(node(i,w)); 47 } 48 dfs(1,0,-1); 49 cout<<n-ans<<endl; 50 return 0; 51 }
以上是关于Codeforces 682C Alyona and the Tree (树上DFS+DP)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #381 (Div. 2) Alyona and mex
CodeForces 740A Alyona and copybooks
CodeForces 740C Alyona and mex