题目描述: 给你一棵树,现在让你选取里面的一些点使得只有偶数个孩子且权值最大,(父节点可以与孙子相连)
分析:  原题版描述的是领导和员工,当时没想到是树结构~~~~~~,现在分析 每个点要保证是偶数点有两种情况 dp[u][0]=dp[u][1]+dp[v][1]  u表示父节点,v表示子节点,0表示有偶数个孩子,1表示有奇数个孩子 ,得状态转移方程:
dp[u][1] = max(dp[u][1]+dp[v][0],dp[u][0]+dp[v][1]);
dp[u][0] = max(dp[u][0]+dp[v][0],dp[u][1],dp[u][1]);
为了防止第一个dp[u][1]干扰第二个运算,所以提前设置好变量;
还有一个状态转移方程,看题解理解吧;
注意最后是dp[1][1] 因为还要加上boss的效率是奇数,起始状态都是0个所以效率为0,不可能有奇数个所以设置为负无穷大表示不可能去得到;
最后总结下第一次接触树型dp的理解:
相比一般的这里用的是递归(dfs)进行状态转移,并且枚举的是边,(对应独立两种状态,所以用了两个状态转移方程,可理解为三维dp);

ac代码:
#include<bits/stdc++.h>
using namespace std;
vector<int> tree[2*100000+4];
long long dp[2*100000+3][2];
int value[2*100000+4];
void dfs(int x){
    dp[x][0]=0;  dp[x][1]=-200000000005;
    for(int i=0,sz=tree[x].size();i<sz;i++){
        int v=tree[x][i];
        dfs(v);
        long long tmp1=dp[x][1],tmp0=dp[x][0];
        dp[x][0]=max(tmp0+dp[v][0],tmp1+dp[v][1]);
        dp[x][1]=max(tmp1+dp[v][0],tmp0+dp[v][1]);
    }
    dp[x][1]=max(dp[x][0]+value[x],dp[x][1]);
}
int main(){
//    freopen("1.txt","r",stdin);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x>>value[i];
        if(i==1)continue;
        tree[x].push_back(i);
    }
    dfs(1);
    cout<<dp[1][1]<<endl;
}