POJ Anniversary party 树形DP

/*

树形dp:

给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大

对于每一个节点,我们有两种状态

dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能获得的最大权值和 

dp[i][1]表示选择节点i ,同上!



转移方程:

dp[i][0]+=max(dp[i_son][1],dp[i_son][0])如果没选择的话,那么子树可选择可不选择 

dp[i][1]+=dp[i_son][0] 选择了之后,子树只能不选择

最后输出max(dp[i][0],dp[i][1])即可

*/ 

 

#include<iostream>

#include<stdio.h>

#include<cstring>

#include<algorithm>

#include<queue>

#include<vector>

using namespace std;

#define maxn 6002

vector<int> v[maxn];

bool b[maxn];

int dp[maxn][2],hp[maxn];

void dfs(int k)

{

    int i,len=v[k].size();

    dp[k][0]=0 ;

    dp[k][1]=hp[k];

    if(len==0)

    return ;

    for(i=0;i<len;i++)

    {

        dfs(v[k][i]);

        dp[k][0]+=max(dp[v[k][i]][1],dp[v[k][i]][0]);

        dp[k][1]+=dp[v[k][i]][0];

    }

}

int main()

{

    int i,n;

    int k,l;

    while(cin>>n)

    {

        for(i=1;i<=n;i++)

        cin>>hp[i],v[i].clear();

        memset(b,0,sizeof(b));

        while(cin>>l>>k&&k||l)

        {

            v[k].push_back(l);

            b[l]=1;

        }

        for(i=1;i<=n;i++)

        {

            if(!b[i])

                break;

        }

        b[i]=1;

        dfs(i);

        cout<<max(dp[i][1],dp[i][0])<<endl;

    }

    return 0;

}

 

你可能感兴趣的:(part)