考点: 树形
d
p
dp
dp
思路:
d
p
[
u
]
[
0
]
dp[u][0]
dp[u][0]表示第u 个结点不去产生的最大价值,
d
p
[
u
]
[
1
]
dp[u][1]
dp[u][1]表示第u 个结点去产生的最大价值,状态转移方程为,设j 为u 的儿子结点:
{
d
p
[
u
]
[
0
]
=
d
p
[
u
]
[
0
]
+
∑
m
a
x
(
d
p
[
j
]
[
1
]
,
d
p
[
j
]
[
0
]
)
d
p
[
u
]
[
1
]
=
d
p
[
u
]
[
1
]
+
∑
d
p
[
j
]
[
0
]
+
w
[
u
]
\begin{cases} dp[u][0] = dp[u][0] + \sum{max(dp[j][1], dp[j][0])}\\ \\ dp[u][1] = dp[u][1] + \sum{dp[j][0]} + w[u]\end{cases}
??????dp[u][0]=dp[u][0]+∑max(dp[j][1],dp[j][0])dp[u][1]=dp[u][1]+∑dp[j][0]+w[u]?
从根结点
d
f
s
dfs
dfs一遍即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int h[N], ne[N], e[N], idx;
int w[N];
LL dp[N][2];
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
LL dfs(int u){
dp[u][1] = w[u];
for(int i = h[u]; ~i; i = ne[i]){
int j = e[i];
dfs(j);
dp[u][0] = dp[u][0] + max(dp[j][1], dp[j][0]);
dp[u][1] = dp[u][1] + dp[j][0];
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin >> n;
memset(h, -1, sizeof h);
for(int i = 2; i <= n; i ++ ){
int x;
cin >> x;
add(x, i);
}
for(int i = 1; i <= n; i ++ ){
cin >> w[i];
}
dfs(1);
LL ans = -1;
for(int i = 1; i <= n; i ++ ){
ans = max({ans, dp[i][1], dp[i][0]});
}
cout << ans;
}
|