Anniversary party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8386 Accepted Submission(s): 3641
L K
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line
0 0
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
5
题目大意:
有一个party,希望邀请一个公司内的n个人,这n个人中,有的人有一个直接的上司,而有直接上司的人不想和上司同时参加这个party。每个人有一个愉快度,怎样选择可以让参加party的人的愉快度和最大。
解题思路:
简单树形dp,dp[i][0]表示第i个人不来时他的下属(直接下属,间接下属)可以获得的最大愉快度,dp[i][1]表示第i个人来时他和他的下属(直接下属,间接下属)可以获得的最大愉快度。
代码:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <cstring>
using namespace std;
int n;
int father[6005],dp[6005][2],v[6005];
vector<int> son[6005];
int dfs(int x){
if(dp[x][1]) return max(dp[x][1],dp[x][0]);
dp[x][1] = v[x];
for(int i = 0; i < son[x].size(); i ++){
dfs(son[x][i]);
dp[x][0] += max(dp[son[x][i]][0],dp[son[x][i]][1]);
dp[x][1] += dp[son[x][i]][0];
}
return max(dp[x][1],dp[x][0]);
}
int main()
{
int l,k;
while(scanf("%d",&n) != EOF){
memset(father,0,sizeof(father));
memset(son,0,sizeof(son));
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i ++) son[i].clear();
for(int i = 1; i <= n; i ++){
scanf("%d",&v[i]);
}
while(true){
scanf("%d%d",&l,&k);
if(l == 0) break;
father[l] = k;
son[k].push_back(l);
}
int ans = 0;
for(int i = 1; i <= n; i ++){
if(father[i] == 0) ans += dfs(i);
}
printf("%d\n",ans);
}
return 0;
}
211



被折叠的 条评论
为什么被折叠?



