题意/Description:
太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。
皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状;某些宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。
可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。
读入/Input:
帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。
输出/Output:
输入文件中数据表示一棵树,描述如下:
第1行 n,表示树中结点的数目。
第2行至第n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号i(0 对于一个n(0 < n<=1500)个结点的树,结点标号在1到n之间,且标号不重复。
题解/solution:
题目说的很清楚,用最少的点覆盖所有的点。题目给出的是个树,所以可以用动态规划来解决。
F[i,0] = min{∑(min(F[j][0],F[j,2]))+F[k,2]}
其中k为枚举的必放的儿子节点,j为除了k之外的儿子节点
F[i,1] =∑(min(F[j,0],F[j,2]))
j是i的儿子节点
对于叶节点i,F[i,0] = F[i,2] = data[i],F[i,1] = 0;
讲得已经十分详细了,剩下自己解决吧。
代码/Code:
var
son:array [0..1501,0..1501] of longint;
f:array [0..1501,1..3] of longint;
a,l:array [0..1501] of longint;
n,x,t:longint;
function min(o,p:longint):longint;
begin
if oj then
k:=k+min(f[son[x,j],1],f[son[x,j],3]);
f[x,1]:=min(f[x,1],k+f[son[x,i],3]);
end;
f[x,2]:=0;
for i:=1 to l[x] do
f[x,2]:=f[x,2]+min(f[son[x,i],1],f[son[x,i],3]);
f[x,3]:=a[x];
for i:=1 to l[x] do
f[x,3]:=f[x,3]+min(f[son[x,i],1],min(f[son[x,i],2],f[son[x,i],3]));
end;
procedure init;
var
i,j:longint;
d:array [0..1501] of longint;
begin
readln(n);
fillchar(d,sizeof(d),0);
for i:=1 to n do
begin
read(x,a[x],l[x]);
for j:=1 to l[x] do
begin
read(son[x,j]);
inc(d[son[x,j]]);
end;
readln;
end;
for i:=1 to n do
if d[i]=0 then
begin
t:=i;
break;
end;
end;
begin
init;
main(t);
write(min(f[t,1],f[t,3]));
end.