日常来道水题233
题目描述
某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。
输入输出格式
输入格式:
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0 0
输出格式:
输出最大的快乐指数。
输入输出样例
输入样例#1:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出样例#1:
5
考虑每个人是否要来,传递一下就行
code:
//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define f(a,b,c) for(int a=b;a<=c;a++)
using namespace std;
int rd() {
int x=0,fla=1; char c=' ';
while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
return x*fla;
}
const int MAX=7010;
const int INF=0x3f3f3f3f;
int n,rt;
int du[MAX],f[MAX][2]; //1表示参加 0表示不参加
vector <int> son[MAX];
void dfs(int x) {
int num=son[x].size();
f(i,0,num-1) {
int y=son[x][i];
dfs(y);//先递归再计算
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main() {
n=rd();
f(i,1,n) f[i][1]=rd();
f(i,1,n) {
int a=rd(),b=rd();
if(!a&&!b) continue;
du[a]++;
son[b].push_back(a);
}
f(i,1,n) if(!du[i]) { rt=i; break; }
dfs(rt);
printf("%d",max(f[rt][1],f[rt][0]));
return 0;
}