您的位置:首页 > 其它

CODEVS 1380没有上司的舞会

2016-11-11 10:50 344 查看
#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点取或不取的最大值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: