算法:树形DP
这道题的影子就来源于URAL上的一道经典题—苹果树,只不过把点权改成了边权,利用那道题的方法可以解决这道题。
总的根是1,这一点在题目中已经有表明。确定别的边可以直接循环查找,因为最大的n只有100。
program inform;
const
maxn=100;
var
d,f:array [0..maxn,0..maxn] of longint;
b:array [0..maxn] of boolean;
n,m,mm:longint;
procedure init;
var
i,x,y,dis:longint;
begin
readln(n,m,mm);
inc(m);//点数=边数+1
for i:=1 to n do
begin
readln(x,y,dis);
d[x,y]:=dis;
d[y,x]:=dis;
end;
end;
procedure dfs(t,sum:longint);
var
i,j,l,r,t1,t2:longint;
begin
l:=0;
r:=0;
for i:=1 to n do
begin
if (not b[i]) and (d[t,i]>0) then
begin
b[i]:=true;
if l=0 then
begin
l:=i;
t1:=d[t,i];
end
else
begin
r:=i;
t2:=d[t,i];
end;
end;
end;
if l<>0 then
begin
dfs(l,t1);
dfs(r,t2);
end;
for i:=1 to m do
begin
for j:=0 to i-1 do
if f[t,i]<f[l,j]+f[r,i-j-1]+sum then f[t,i]:=f[l,j]+f[r,i-j-1]+sum;
end;
end;
procedure main;
begin
fillchar(b,sizeof(b),false);
b[1]:=true;
dfs(1,0);
writeln(f[1,m]>=mm);
writeln(f[1,m]-mm);
end;
begin
assign(input,'inform.in'); reset(input);
assign(output,'inform.out'); rewrite(output);
init;
main;
close(input); close(output);
end.
175

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



