首页 > 代码库 > POJ Anniversary party 树形DP

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 6002vector<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;}

 

POJ Anniversary party 树形DP