您的位置:首页 > 其它

皇宫看守 树型动态规划

2016-05-12 18:17 190 查看
题目大意

  太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。 

  皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状;某些宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫     殿安排看守所需的费用不同。 

  可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

 

分析

  首先定义:     

    F[T,1] 表示在x点放置守卫的最小费用    

    F[T,2] 表示在x点不放置守卫,同时x点可以或没有儿子节点可以监视到

    F[T,3] 表示在x点不放置守卫,同时x点一定要给儿子节点监视到

  转移方程为F[x,1]=sigma{min(F[y,1],F[y,2],F[y,3])}+w[x]

            F[x,2]=sigma{min(F[y,1],F[y,3])}

            F[x,3]=sigma{min(F[z,1],F[z,3])+F[y,1]}  y<>z  y,z分别为x的子节点                      

  具体见:http://blog.csdn.net/fisher_jiang/article/details/2488506

  

代码

  

var
a:array[0..7000,0..7000] of longint;
f:array[0..7000,0..2] of longint;
w:array[0..7000] of longint;
v:array[0..7000] of boolean;
i,j,k,l:longint;
n,m:longint;

function min(x,y:longint):longint;
begin
if x<y
then exit(x)
else exit(y);
end;

procedure dfs(r:longint);
var
i,j,k:longint;
c,t,ii:longint;
begin
v[r]:=false;
if a[r,0]=0
then
begin
f[r,0]:=w[r];
f[r,1]:=0;
f[r,2]:=w[r];
exit;
end;
for i:=1 to a[r,0] do
if v[a[r,i]] then dfs(a[r,i]);
t:=0;
for i:=1 to a[r,0] do
begin
c:=a[r,i];
t:=t+min(f[c,0],f[c,2]);
end;
f[r,2]:=maxlongint;
ii:=t;
for i:=1 to a[r,0] do
begin
c:=a[r,i];
f[r,0]:=f[r,0]+min(min(f[c,0],f[c,1]),f[c,2]);
f[r,1]:=f[r,1]+min(f[c,0],f[c,2]);
t:=t-min(f[c,0],f[c,2])+f[c,0];
f[r,2]:=min(f[r,2],t);
t:=ii;
end;
f[r,0]:=f[r,0]+w[r];
end;

begin
readln(n);
fillchar(v,sizeof(v),1);
for i:=1 to n do
begin
read(j,w[j],a[j,0]);
for k:=1 to a[j,0] do
begin
read(l);
a[j,k]:=l;
v[l]:=false;
end;
readln
end;
for i:=1 to n do
if v[i] then break;
fillchar(v,sizeof(v),1);
dfs(i);
write(min(f[i,0],f[i,2]));
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: