POJ2342 简单树形dp

来源:互联网 发布:windows defender 卸载 编辑:程序博客网 时间:2024/04/30 00:12

因为在做HDU4126的时候需要使用树形dp,然而我对树形dp一点也不了解,所以做一下树形dp的题来加深其了解,

题目不说了


dp方程是 :  dp[i][0] += max(dp[j][0],dp[j][1]) //i是j的父亲

dp[i][1] += dp[j][0] 


其中dp[i][0] 表示该人没来

dp[i][1]表示该人来了


贴代码


#include <cstdio>#include <iostream>#include <vector>#include <cstring>using namespace std;//常量const int N_MAX = 6005;//变量int root; // 根节点int par[N_MAX]; //爹节点,最后通过该数组找到根节点vector<int > Ve[N_MAX];//邻接表表示树形结构int dp[N_MAX][2];//dp[i][0] 表示i不去,dp[i][1]表示i去了int dfs(int n){    for(int i=0; i<Ve[n].size();i++)    {        dfs(Ve[n][i]);        dp[n][1] += dp[Ve[n][i]][0];        dp[n][0] += max(dp[Ve[n][i]][1],dp[Ve[n][i]][0]);    }}int main(){    int N;    while(scanf("%d%d", &N, &dp[1][1])!=EOF)    {        int x, y;        int res = 0;        memset(Ve,0,sizeof(Ve));        memset(par,0,sizeof(par));        if(N==0 && dp[1][1]==0)break;        for(int i=2; i<=N; i++)scanf("%d", &dp[i][1]);        for(int i=0; i<N-1; i++)        {            scanf("%d%d", &x, &y);            par[x] = y;            Ve[y].push_back(x);        }        for(int i=1; i<=N; i++)        {            if(par[i] == 0)            {                root = i;                break;            }        }        dfs(root);        res = max(dp[root][1],dp[root][0]);        printf("%d\n",res);    }}


0 0
原创粉丝点击