codevs 1380 沒有上司的舞會


題目描述 Description
Ural大學有N個職員,編號為1~N。他們有從屬關系,也就是說他們的關系就像一棵以校長為根的樹,父結點就是子結點的直接上司。每個職員有一個快樂指數。現在有個周年慶宴會,要求與會職員的快樂指數最大。但是,沒有職員願和直接上司一起與會。

輸入描述 Input Description
第一行一個整數N。(1<=N<=6000)
接下來N行,第i+1行表示i號職員的快樂指數Ri。(-128<=Ri<=127)
接下來N-1行,每行輸入一對整數L,K。表示K是L的直接上司。
最后一行輸入0,0。

輸出描述 Output Description
輸出最大的快樂指數。

樣例輸入 Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

思路
樹形dp+dfs
二維數組dp[a][2]

dp[a][1]表示a號人,去;則他的下屬不能去,即 dp[a][1]應當包括他本身的快樂值,以及他的所有下屬不去的dp值;
dp[a][1]+=dp[下屬們][0];dp[a][1]+=num[x];

dp[a][0]表示a號人,不去;則他的下屬可去可不去,取較大值;
dp[a][0]+=max(dp[下屬們][1],dp[下屬們][0]);
dfs深搜找下屬;
注意:在代碼深搜中的j要為局部變量,否則在回溯過程中j將不能返回上一層的值,非tle即wa即re;
慎用全局變量!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
const int maxn=6000+50;
using namespace std;
int n,k,l;
int num[maxn];
int fa[maxn];
vector<int> map[maxn];
int dp[maxn][2];

int dfs(int x,int a){
if(dp[x][a])
return dp[x][a];
if(a==1){
dp[x][1]=num[x];
for(int j=0;j<map[x].size();j++){
dp[x][1]+=dfs(map[x][j],0);
}

}
if(a==0){
dp[x][0]=0;
for(int j=0;j<map[x].size();j++){
dp[x][0]+=max(dfs(map[x][j],0),dfs(map[x][j],1));
}

}
return dp[x][a];
}


int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
for(int i=1;i<=n;i++){
scanf("%d%d",&l,&k);
map[k].push_back(l);
fa[l]=k;
}
for(int i=1;i<=n;i++){
if(fa[i]==0) {
cout<<max(dfs(i,0),dfs(i,1));
return 0;
}
}
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com