[题目大意]
  • 给定一棵树,在某一个点上放置一个基站需要花费1单位的代价,可以覆盖自己和相邻的点,求覆盖所有点的最小代价。

[分析题解]
  •  对于一个点来说,其能被覆盖只有三种方法:父亲放置基站,自己放置基站,某个儿子放置基站。这样的话可以想到枚举状态来动态规划。
  • 动态规划的状态表示方法是非常多的,我的表示比较繁琐,是这样的,先建立有根树,然后用F[I,J]表示以I为根的子树,状态为J的最小覆盖代价。
  • J=0代表I的父亲没有放,I不放置。这样,就要从I的儿子中找一个放基站,才能保证I被覆盖。其他的儿子随意。
  • J=1代表I的父亲放置了,I不放置。这样I的儿子可以随意,爱放不放,反正I已经被覆盖,儿子的事情那是子问题里需要解决的。
  • J=2代表I的父亲没有放,I放置了。既然I已经放置了,儿子也是随意放。但是代价要+1,因为在I处放置了一个。
  • J=3代表I的父亲放置了,I放置了。同上。其实2、3可以合并为一种情况,为了显得厉害一些(其实是脑子小),就拆成两个了。
  • 这样按照定义转移一下就好了,最后输出Min(F[Root,0],F[Root,2]);

[个人代码]
  1 //10082338      perseawe        3659    Accepted        1356K   79MS    Pascal  2528B   2012-04-16 22:41:13 
  2 
  3 Const
  4   MaxNode=10000+100;
  5   MaxEdge=MaxNode*2;
  6   Inf=1000000;
  7 
  8 Var
  9   n,tot:Longint;
 10   Flag:Array [0..MaxNode] of Boolean;
 11   hv,Line,lv,Father:Array [0..MaxNode] of Longint;
 12   F:Array [0..MaxNode,0..3of Longint;
 13   Edge:Array [0..MaxEdge] of Record next,wh:Longint;end;
 14 
 15 Function Min(a,b:Longint):Longint;begin if a<b then exit(a);exit(b);end;
 16 
 17 Procedure AddEdge(u,v:Longint);
 18   begin
 19     inc(tot);
 20     Edge[tot].next:=hv[u];hv[u]:=tot;
 21     Edge[tot].wh:=v;
 22     inc(tot);
 23     Edge[tot].next:=hv[v];hv[v]:=tot;
 24     Edge[tot].wh:=u;
 25   end;
 26 
 27 Procedure Init;
 28   var
 29     i,u,v:Longint;
 30   begin
 31     readln(n);
 32     for i:=1 to n-1 do
 33       begin
 34         readln(u,v);
 35         AddEdge(u,v);
 36       end;
 37   end;
 38 
 39 Procedure BFS_Lebal;
 40   var
 41     I,tnode,u,v,top,tail:Longint;
 42   begin
 43     For I:=N downto 1 do
 44       begin
 45         F[I,0]:=Inf;
 46         F[I,1]:=0;
 47         F[I,2]:=1;
 48         F[I,3]:=1;
 49       end;
 50     Fillchar(lv,sizeof(lv),0);Lv[1]:=1;
 51     top:=0;tail:=1;Line[1]:=1;
 52     Repeat
 53       inc(top);
 54       u:=Line[top];
 55       tnode:=hv[u];
 56       while tnode<>0 do
 57         begin
 58           v:=Edge[tnode].wh;
 59           if lv[v]=0 then
 60             begin
 61               F[u,0]:=0;
 62               lv[v]:=lv[u]+1;
 63               Father[v]:=u;
 64               inc(tail);
 65               Line[tail]:=v;
 66             end;
 67           tnode:=Edge[tnode].next;
 68         end;
 69     Until top=tail;
 70   end;
 71 
 72 Procedure DP;
 73   var
 74     I,u,v,Tmp,Tnode,Plus:Longint;
 75   begin
 76     Fillchar(Flag,Sizeof(Flag),False);
 77     For I:=N downto 1 do
 78       begin
 79         u:=Line[I];
 80         //UpDate F[u,0]
 81         if not(Flag[u]) then
 82           begin
 83             tnode:=hv[u];
 84             Tmp:=MaxLongint;Plus:=0;
 85             While tnode<>0 do
 86               begin
 87                 v:=Edge[tnode].wh;
 88                 if lv[u]+1=lv[v] then if F[v,2]<Tmp then begin Tmp:=F[v,2];Plus:=F[v,2]-F[v,0];end;
 89                 tnode:=Edge[tnode].next;
 90               end;
 91             Inc(F[u,0],Plus);
 92           end;
 93         //UpDate His Father
 94         Tmp:=Min(F[u,0],F[u,2]);
 95         Inc(F[Father[u],0],Tmp);
 96         Inc(F[Father[u],1],Tmp);
 97         If Tmp=F[u,2then Flag[Father[u]]:=True;
 98 
 99         Tmp:=Min(F[u,1],F[u,3]);
100         Inc(F[Father[u],2],Tmp);
101         Inc(F[Father[u],3],Tmp);
102       end;
103   end;
104 
105 Procedure Main;
106   begin
107     BFS_Lebal;
108     DP;
109   end;
110 
111 Procedure Print;
112   begin
113     writeln(Min(F[1,0],F[1,2]));
114   end;
115 
116 Begin
117   assign(INPUT,'tower.in');Reset(INPUT);
118   Init;
119   Close(INPUT);
120   Main;
121   assign(OUTPUT,'tower.out');Rewrite(OUTPUT);
122   Print;
123   Close(OUTPUT);
124 End.

相关文章: