题目大意
- 给出一棵带权值的树;
- 如果父亲出席,则儿子们都不出席舞会;
- 如果父亲不出席,儿子们可以选择出席与否;
- 求最大的权值和。
题目分析
- f[x][1] 表示 x 会出席晚会,所以他的儿子都不出席,取和:
f[x][1]=∑y∈son[x]f[y][0]
- f[x][0] 表示 x 不出席晚会,所以他的儿子可以选择出席与否,取最大值:
f[x][0]=∑y∈son[x]Max(f[y][0],f[y][1])
解题流程
- 矩阵存图,记录父子关系;
- 找到第一个跟,开始搜索;
- 回溯更新;
- 答案:ans=max(f[root][0],f[root][1])
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=6005;
int f[N][3],fa[N];
int so[N][N];
int n,ans;
void dfs(int x){
if(!so[x][0]) return ;
for(int i=1;i<=so[x][0];i++){
int y=so[x][i];
dfs(y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&f[i][1]);
int x,y;
for(int i=1;i<n;i++) {
scanf("%d %d",&x,&y);
so[y][0]++;
fa[x]++;
so[y][so[y][0]]=x;
}
int ro;
for(int i=1;i<=n;i++) {
if(!fa[i]) {
ro=i;
break;
}
}
dfs(ro);
ans=max(f[ro][0],f[ro][1]);
cout<<ans;
return 0;
}