解题思路:
- 题目规定不能连续相邻两个房间偷,令dpi,0/1来表示节点i为根可以偷到的最大价值,最终结果即max(dp1,0,dp1,1)。
- 假设i被偷,则有:dpi,1+=dpi′s son,0
- 假设i没被偷, 则有dpi,0+=max(dpi′s son,0,dpi′s son,1)注意i即使不偷,i的孩子也可以偷或不偷,而不是一定要偷,取最大值即可。
#include<bits/stdc++.h>
using namespace std;
struct edge{
int to, next;
}es[200005];
int head[100005], w[100005];
int cnt = 0;
void add_edge(int from, int to){//建图
es[++cnt].to = to;
es[cnt].next = head[from];
head[from] = cnt;
}
int dp[100005][2];
void solve(int i){
for(int j = head[i]; j; j = es[j].next){
solve(es[j].to);//先处理son
dp[i][1] += dp[es[j].to][0];//在偷的情况下,应该是其son不偷的情况下的最大值。
dp[i][0] += max(dp[es[j].to][0],dp[es[j].to][1]);//在不偷的情况下,应该取son偷或不偷所产生的最大值。
}
return;
}
int main(){
int n;
int root;
cin>>n;
for(int i = 1; i <= n; ++i) cin>>dp[i][1];//初始化dp
for(int i = 1; i <= n; ++i){
int fa;
cin>>fa;
if(fa == 0) root = i;
else{
add_edge(fa, i);
}
}
solve(root);
cout<<max(dp[root][0], dp[root][1]);
return 0;
}