Anniversary party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10129 Accepted Submission(s): 4289
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
第一道树形dp
dp【i】【0】是第i个人不来时的“”rating”最大值
dp【i】【1】是第i个人来时的“rating”最大值
所以dp【i】【0】=∑max(dp【j】【0】,dp【j】【1】) ,其中j是i的直系下属,第一次写的时候忘了注意要取这两个里的最大值,因为i不来时,j可以来也可以不来
dp【i】【1】=∑dp【j】【0】 (j是i的直系下属)
用vector存每个人的直系下属
类似后序遍历这颗树即可
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
typedef long long ll;
using namespace std;
int n;
vector <int> w[10000];
int l,k,dp[10000][2],book[10000],fa[10000];
int tree_dp(int x)
{
int t;
book[x]=1;
for(int i=0;i<w[x].size();i++)
{
t=w[x].at(i);
if(fa[t]==x&&!book[t])
{
// printf("%d\n",t);
tree_dp(t);
dp[x][0]+=max(dp[t][1],dp[t][0]);
dp[x][1]+=dp[t][0];
}
}
}
int main()
{
int i;
while(~scanf("%d",&n))
{
memset(book,0,sizeof(book));
for(i=1;i<=n;i++)
{
scanf("%d",&dp[i][1]);
dp[i][0]=0;
fa[i]=i; //为了找根节点,开了一个数组存他的直系父节点,应该也有别的简单的求根节点的方法
w[i].clear();
}
while(scanf("%d %d",&l,&k),l,k)
{
w[k].push_back(l);
fa[l]=k;
}
for(i=1;i<=n;i++)
{
if(fa[i]==i)
{
tree_dp(i);
printf("%d\n",max(dp[i][0],dp[i][1]));
// break;
}
}
}
}
534



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



