本题地址
http://www.luogu.org/problem/show?pid=1352
http://codevs.cn/problem/1380/
题目描述
某大学有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
思路
树型DP
var f:array[1..6000,0..1] of longint; //f[i,0]表示以i为根的子树上司i不去时的最大价值;f[i,1]表示以i为根的子树上司i去时的最大价值 son:array[1..6000,0..200] of longint; //son[i,0]表示i结点的儿子总数,son[i,j]表示结点i的第j个儿子 a,fa:array[0..6000] of longint; n,root:longint; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; procedure work(x:longint); var i:longint; begin if son[x,0]=0 then begin f[x,1]:=a[x]; exit; end; for i:=1 to son[x,0] do work(son[x,i]); f[x,1]:=a[x]; for i:=1 to son[x,0] do begin inc(f[x,1],f[son[x,i],0]); inc(f[x,0],max(f[son[x,i],1],f[son[x,i],0]));//TIPS:当上司不去的时候员工可以去也可以不去 end; end; //DP的过程 procedure init; var i,x,y:longint; begin readln(n); for i:=1 to n do readln(a[i]); for i:=1 to n-1 do begin readln(x,y); inc(son[y,0]); son[y,son[y,0]]:=x; fa[x]:=y; end; readln(x,y); end; function find():longint; var i:longint; begin for i:=1 to n do if fa[i]=0 then exit(i); end; //哪个节点是树的根 begin fillchar(f,sizeof(f),0); fillchar(fa,sizeof(fa),0); fillchar(son,sizeof(son),0); init; root:=find(); work(root); writeln(max(f[root,1],f[root,0])); end.
时间: 2024-10-10 10:16:08