題目大意
- 給出一棵帶權值的樹;
- 如果父親出席,則兒子們都不出席舞會;
- 如果父親不出席,兒子們可以選擇出席與否;
- 求最大的權值和。
題目分析
- 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;
}