2021 ICPC 南京 H-Crystalfly(树上DP)
Probelm Statement
你一开始处于 1 1 1号节点的树, 每个点 a i a_i ai个蝴蝶, 且如果 i t h i^{th} ith节点的父节点被扰动时, 这些蝴蝶会在 t i ( 1 ≤ t i ≤ 3 ) t_i(1leq t_ileq 3) ti(1≤ti≤3)时刻后消散. 求你可以抓到多少只蝴蝶.
Solution
当我们第一次到达节点 u u u的时候它的所有儿子都会被激活,对于 u u u的子节点 v v v, 我们只有两个决策, 要么到达子节点 v v v知乎继续向下, 那么 u u u的其他子节点上的蝴蝶都无法再次抓取. 或者我们进入某个子节点 v 1 ( t v 1 = 3 ) v_1(t_{v_1}=3) v1(tv1=3)后立刻返回节点 u u u挑另一个子节点 v 2 v_2 v2直接走下去, 然后除了 v 1 , v 2 v_1,v_2 v1,v2以外 u u u的其他子节点上的蝴蝶都会消失.
我们不妨设:
- f i f_i fi: 我们取节点 i i i, 可以取 i i i子节点上的蝴蝶可以收获的最大蝴蝶数.
- g i g_i gi: 我们不取节点 i i i上的蝴蝶, 可取 i i i子节点上的蝴蝶的最大蝴蝶数.
- h i h_i hi: 我们节点 i i i上的蝴蝶, 但是不取 i i i子节点上的蝴蝶可以收获的最大蝴蝶数.
对于 h u h_u hu根据上述定义我们可以得到, h u = ∑ v ∈ son u g v + a u h_u=sumlimits_{vintext{son}u}g_v+a_u hu=v∈sonu∑gv+au.
由于 f u f_u fu和 g u g_u gu的区别主要在于节点 u u u上的蝴蝶去不去得到, 我们有 f u = g u + a u f_u=g_u+a_u fu=gu+au.
接下来我们考虑计算 g u g_u gu根据上述两种两种决策:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77# define Fast_IO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); # include "unordered_map" # include "algorithm" # include "iostream" # include "cstdlib" # include "cstring" # include "cstdio" # include "vector" # include "bitset" # include "queue" # include "cmath" # include "map" # include "set" using namespace std; const int maxm=1e5+10; int Task,N; long long A[maxm]; int T[maxm]; long long F[maxm],G[maxm],H[maxm]; vector<int> Edge[maxm]; void Dfs(int Now,int Father){ long long Max1,Max2,Max; Max=Max1=Max2=0; long long Res=0; for(auto To:Edge[Now]){ if(To==Father) continue; Dfs(To,Now); }H[Now]=A[Now]; for(auto To:Edge[Now]){ if(To==Father) continue; H[Now]+=G[To]; } for(auto To:Edge[Now]){ if(To==Father) continue; Res+=G[To]; Max=max(A[To],Max); }G[Now]=Res+Max; Max1=Max2=0; for(auto To:Edge[Now]){ if(To==Father || T[To]!=3) continue; if(A[To]>=Max1) Max2=Max1,Max1=A[To]; else Max2=max(Max2,A[To]); } for(auto To:Edge[Now]){ if(To==Father) continue; if(A[To]!=Max1 || T[To]!=3) G[Now]=max(G[Now],Res-G[To]+H[To]+Max1); else G[Now]=max(G[Now],Res-G[To]+H[To]+Max2); } F[Now]=G[Now]+A[Now]; return; } inline void Solve(){ static int i,U,V; scanf("%d",&N); for(i=1;i<=N;i++) Edge[i].clear(),F[i]=G[i]=false; for(i=1;i<=N;i++) scanf("%lld",&A[i]); for(i=1;i<=N;i++) scanf("%d",&T[i]); for(i=1;i< N;i++){ scanf("%d%d",&U,&V); Edge[U].push_back(V); Edge[V].push_back(U); }Dfs(1,1); printf("%lldn",F[1]); return; } int main(){ scanf("%d",&Task); while(Task--) Solve(); return 0; }
Orz dls
算法来源: Namomo Camp Day1.
Link
Codeforces Gym: The 2021 ICPC Asia Nanjing Regional Contest(XXII Open Cup,Grand Prix of Nanjing).
Vjudge: Namomo Spring Camp 2022 Div1 Week1 A.
最后
以上就是欣慰御姐最近收集整理的关于2021 ICPC 南京 H-Crystalfly(树上DP)2021 ICPC 南京 H-Crystalfly(树上DP)的全部内容,更多相关2021内容请搜索靠谱客的其他文章。
发表评论 取消回复