hdu 1520 Anniversary party(树形DP)

来源:互联网 发布:手机游戏优化器在哪 编辑:程序博客网 时间:2024/06/10 09:55

本题可用树形DP求解(即在树上DP).

father数组记录节点父亲,ch容器记录儿子。

dp[i][0]表示以节点i为跟的子树的最大总权值(不选点i),dp[i][1]表示选点i。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<set>#include<map>#include<vector>#include<cmath>#define ll __int64#define INF 0x3fffffff#define MAXN 6005using namespace std;int n;int dp[MAXN][2];int a[MAXN],father[MAXN],vis[MAXN];vector<vector<int> >ch(6005);void tree_dp(int root){    vis[root]=1;    for(int i=0;i<ch[root].size();i++) {        int j=ch[root][i];        if(!vis[j]) {            tree_dp(j);            dp[root][0]+=max(dp[j][1],dp[j][0]);            dp[root][1]+=dp[j][0];        }    }}int main(){    //freopen("d:\\Test.txt","r",stdin);    while(~scanf("%d",&n)) {        for(int i=1; i<=n; i++) scanf("%d",&a[i]);        memset(vis,0,sizeof(vis));        memset(dp,0,sizeof(dp));        memset(father,0,sizeof(father));        for(int i=0;i<=n;i++) ch[i].clear();        for(int i=1; i<=n; i++) dp[i][1]=a[i];        int c,f;        while(scanf("%d%d",&c,&f),c||f) {            father[c]=f;            ch[f].push_back(c);        }        int root=1;        while(father[root]) root=father[root];        tree_dp(root);        cout<<max(dp[root][0],dp[root][1])<<endl;    }    return 0;}

0 0
原创粉丝点击