【vijos1144】小胖守皇宫(树形DP)

描述

huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫。

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

可是xuzhenyi手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。

帮助xuzhenyi布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

格式

输入格式

输入文件中数据表示一棵树,描述如下:

第1行 n,表示树中结点的数目。

第2行至第n+1n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号i(0<in0<i≤n),在该宫殿安置侍卫所需的经费k,该点的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号r1,r2,,rmr1,r2,⋯,rm

对于一个n(0<n15000<n≤1500)个结点的树,结点标号在1到n之间,且标号不重复。保证经费总和不超过2^31-1

输出格式

输出文件仅包含一个数,为所求的最少的经费。

 

思路:dp[i,0..2]分别表示在i的某个儿子,i本身,i的父亲安置侍卫覆盖i的整个子树的最小花费

        dp[u,0]=dp[v,1]+sigma(min(dp[v',0],dp[v',1]))   v<>v'

        dp[u,1]=a[u]+sigma(min(dp[v,0],dp[v,1],dp[v,2]))

        dp[u,2]=sigma(min(dp[v,0],dp[v,1]))

 1 var dp:array[1..10000,0..2]of longint;
 2     head,vet,next,a:array[1..10000]of longint;
 3     n,m,i,j,x,y,tot:longint;
 4 
 5 procedure add(a,b:longint);
 6 begin
 7  inc(tot);
 8  next[tot]:=head[a];
 9  vet[tot]:=b;
10  head[a]:=tot;
11 end;
12 
13 function min(x,y:longint):longint;
14 begin
15  if x<y then exit(x);
16  exit(y);
17 end;
18 
19 procedure dfs(u,pre:longint);
20 var e,v,i,s,d:longint;
21 begin
22  e:=head[u]; dp[u,0]:=maxlongint; dp[u,1]:=a[u]; dp[u,2]:=0;
23  d:=0; s:=0;
24  while e<>0 do
25  begin
26   v:=vet[e];
27   if v<>pre then
28   begin
29    inc(d);
30    dfs(v,u);
31    s:=s+min(dp[v,0],dp[v,1]);
32    dp[u,1]:=dp[u,1]+min(min(dp[v,0],dp[v,1]),dp[v,2]);
33    dp[u,2]:=dp[u,2]+min(dp[v,0],dp[v,1]);
34   end;
35   e:=next[e];
36  end;
37  if d=0 then begin dp[u,0]:=maxlongint; dp[u,1]:=a[u]; dp[u,2]:=0; exit; end;
38  e:=head[u];
39  while e<>0 do
40  begin
41   v:=vet[e];
42   if v<>pre then dp[u,0]:=min(dp[u,0],s-min(dp[v,0],dp[v,1])+dp[v,1]);
43   e:=next[e];
44  end;
45 end;
46 
47 begin
48  //assign(input,'vijos1144.in'); reset(input);
49 // assign(output,'vijos1144.out'); rewrite(output);
50  readln(n);
51  for i:=1 to n do
52  begin
53   read(x); read(a[x]);
54   read(m);
55   for j:=1 to m do
56   begin
57    read(y); add(x,y); add(y,x);
58   end;
59  end;
60  fillchar(dp,sizeof(dp),$1f);
61  dfs(1,-1);
62  writeln(min(dp[1,0],dp[1,1]));
63 
64  //close(input);
65  //close(output);
66 end.

 

      

posted on 2016-11-15 16:44  myx12345  阅读(287)  评论(0编辑  收藏  举报

导航