CODEVS 1380没有上司的舞会

来源:互联网 发布:淘宝食品店铺运营技巧 编辑:程序博客网 时间:2024/06/05 12:45
#include<stdio.h>#include<iostream>#include<vector>using namespace std;vector<int>sons[6010];int n,happiness[6010],father[6010],son,fa,f[6010][5];int mmax(int a,int b){    return a>b?a:b;}int d(int cur,int state){//遍历到cur点 state表示happiness[cur]取或不取    if(f[cur][state]>0) return f[cur][state];    if(sons[cur].size()==0) return f[cur][state]+=(state==1?happiness[cur]:0);//如果cur没有子节点 即cur为叶节点    int sum=0;    if(state==1) sum+=happiness[cur];//注意!!!happiness[cur]只加一次!!!    for(int i=0;i<sons[cur].size();i++){        int tryson=sons[cur][i];        if(state==1){//state==1 则取            sum+=d(tryson,0);        }        if(state==0){//state==0 则不取            int aa=mmax(d(tryson,0),d(tryson,1));            sum+=aa;        }    }    return f[cur][state]=sum;}int main(){    freopen("1380.in","r",stdin);    freopen("1380.out","w",stdout);    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&happiness[i]);    while(1){        scanf("%d %d",&son,&fa);        if(son==fa) break;        sons[fa].push_back(son);//将fa的son导入sons        father[son]=fa;//son的father是fa    }    for(int i=1;i<=n;i++){        if(father[i]==0){//找到根节点了            printf("%d",mmax(d(i,1),d(i,0)));        }    }    return 0;}

题解:树形DP(记忆化搜索),由于不一定是二叉树,所以我用了STL中的vector数组来储存每个节点的子节点。d(cur,state) 其中state表示cur点取或不取的最大值。

0 0
原创粉丝点击