源程序名 party.???( pas, c, cpp)
可执行文件名 party.exe
输入文件名 party.in
输出文件名 party.out
【问题描述】
你要组织一个由你公司的人参加的聚会。你希望聚会非常愉快,尽可能多地找些有趣的
热闹。但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵。给定 N 个人(姓名,
他幽默的系数,以及他上司的名字) ,编程找到能使幽默系数和最大的若干个人。
【输入】
第一行一个整数 N(N<100) 。接下来有 N 行,每一行描述一个人的信息,信息之间用空
格隔开。姓名是长度不超过 20 的字符串,幽默系数是在 0 到 100 之间的整数。
【输出】
所邀请的人最大的幽默系数和。
【样例输入】
party.in
5
BART 1 HOMER
HOMER 2 MONTGOMERY
MONTGOMERY 1 NOBODY
LISA 3 HOMER
SMITHERS 4 MONTGOMERY
【样例输出】
party.out
8
分析:
与没有上司的舞会一样,只是读入有点恶心。
代码:
var
n,i,j,x,y,num,root:longint;
a,aa,bb,cc:array[1..600] of longint;
son:array[1..600,0..600] of longint;
f:array[0..600,0..1] of longint;
w:array[1..600] of longint;
ch:char;
s:string;
nam:array [1..1000] of string;
function max(a,b:longint):longint;
begin
if a>b then
exit(a);
exit(b);
end;
procedure dp(x:longint);
var
i:longint;
begin
if son[x,0]=0 then
begin
f[x,1]:=w[x];
exit;
end;
for i:=1 to son[x,0] do
dp(son[x,i]);
for i:=1 to son[x,0] do
begin
inc(f[x,1],f[son[x,i],0]);
end;
for i:=1 to son[x,0] do
begin
inc(f[x,0],max(f[son[x,i],0],f[son[x,i],1]));
end;
inc(f[x,1],w[x]);
end;
begin
assign(input,'party.in');
assign(output,'party.out');
reset(input);
rewrite(output);
readln(n);
for i:=1 to n do
begin
s:='';
read(ch);
repeat
s:=s+ch;
read(ch);
until ch=' ';
for j:=1 to num do
if nam[j]=s then break;
if nam[j]<>s then
begin
inc(num);
nam[num]:=s;
j:=num;
end;
aa[i]:=j;
read(bb[i]);
readln(s);
while s[1]=' ' do delete(s,1,1);
while s[length(s)]=' ' do delete(s,length(s),1);
for j:=1 to num do
if nam[j]=s then break;
if nam[j]<>s then
begin
inc(num);
nam[num]:=s;
j:=num;
end;
if s='NOBODY' then
root:=aa[i];
cc[i]:=j;
end;
for i:=1 to n do
w[aa[i]]:=bb[i];
for i:=1 to n do
begin
x:=aa[i];
y:=cc[i];
if x=root then continue;
if (x=0) and (y=0) then
break;
a[x]:=y;
inc(son[y,0]);
son[y,son[y,0]]:=x;
end;
dp(root);
writeln(max(f[root,0],f[root,1]));
close(input);
close(output);
end.