树形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;
}

 

posted on 2024-02-17 17:03  风ffff  阅读(16)  评论(3编辑  收藏  举报