树形dp
模型:给定一颗有n个节点的树,任选一个节点为根节点,从而定义出每个节点的深度和每棵子树的根。
树形DP的特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系。利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的搜索的程序。而深搜的特点,就是“不撞南墙不回头”
基本思路:
1.建树
2.列出动态转移方程
典型例题:没有上司的舞会
#include<bits/stdc++.h>
using namespace std;
int n,l,k,ans;
vector<int> son[6600];
int f[6600][2],v[6600],r[6600];
void dp(int x){
f[x][0]=0;
f[x][1]=r[x];
for(int i=0;i<son[x].size();i++){
int y=son[x][i];
dp(y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&r[i]);
}
for(int i=1;i<=n;i++){
cin>>l>>k;
v[l]=1;
son[k].push_back(l);
}
int root;
for(int i=1;i<=n;i++){
if(!v[i]){
root=i;
break;
}
}
dp(root);
ans=max(f[root][0],f[root][1]);
cout<<ans;
return 0;
}