codevs 1380

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1380相关的知识,希望对你有一定的参考价值。

树形动态规划,记忆化搜索实现。

以校长为根建立一棵树。

f[i][0]表示第i个人不去参加,以他为根的子树的最大快乐指数。

f[i][1]表示第i个人去参加,以他为根的子树的最大快乐指数。

f[i][0]=∑max(f[j][0],f[j][1])(j是i的下属)

f[i][1]=∑f[j][0](j是i的下属)

注意如果f数组为负数时返回0。

#include<cstdio>
#include<cctype>
#include<vector>
using namespace std;
int read(){
    char c; while(!isdigit(c=getchar()) && c!=-);
    int x=0,y=1; if(c==-) y=-1; else x=c-0;
    while(isdigit(c=getchar())) x=x*10+c-0; return x*y;
}
vector<int> e[6001];
int r[6001],f[6001][2],vis[6001][2];
bool yes[6001];
int dfs(int o,int p){
    if(vis[o][p]) return f[o][p]; else vis[o][p]=1;
    for(int i=0;i<e[o].size();i+=1)
        if(p==1) f[o][p]+=dfs(e[o][i],0);
        else f[o][p]+=max(dfs(e[o][i],0),dfs(e[o][i],1));
    if(p) f[o][p]+=r[o];
    return f[o][p]>0? f[o][p]:f[o][p]=0;
}
int main(){
    int n=read();
    for(int i=1;i<=n;i+=1) r[i]=read();
    for(int i=1;i<n;i+=1){
        int x=read(),y=read();
        e[y].push_back(x); yes[x]=1;
    }
    for(int i=1;i<=n;i+=1)
        if(!yes[i]) printf("%d",max(dfs(i,0),dfs(i,1)));
    return 0;
}

 

以上是关于codevs 1380的主要内容,如果未能解决你的问题,请参考以下文章

[CODEVS 1380]没有上司的舞会

codevs 1380

Codevs 1380 没有上司的舞会

codevs1380 没有上司的舞会

codevs1380 没有上司的舞会

codevs 1380 没有上司的舞会 - 树形动态规划