例题1:
hdu1520:http://acm.hdu.edu.cn/showproblem.php?pid=1520
题意:
给一颗树,给各个结点的权值,选择若干结点,结点之间不能直接相连,求结点的最大权值和(即任意结点之间没有父子关系)
解析:
树的最大独立集合,在树上dp操作,选了该结点,就一定不能选该结点的子节点
dp[i][0]表示以i为根的树,不选该根结点的权值最大和
dp[i][1]表示以i为根的树,选该根结点的权值最大和
dp[x][0]+=max(dp[v][1],dp[v][0]);
dp[x][1]+=dp[v][0];
先处理子节点,再处理父节点
AC:
用树形dp解决
#include<bits/stdc++.h>
#define MAXN 20005
using namespace std;
int dp[MAXN][2];
int f[MAXN];
vector<int> vc[MAXN];
void dfs(int x)
{
int len=vc[x].size();
for(int i=0;i<len;i++)
{
int v=vc[x][i];//子节点
dfs(v);//要先出来子节点
dp[x][0]+=max(dp[v][1],dp[v][0]);
dp[x][1]+=dp[v][0];
}
}
int main()
{
int n,x,a,b;
while(scanf("%d",&n