[题目大意]
- 给定一棵树,在某一个点上放置一个基站需要花费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..3] of 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,2] then 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.
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..3] of 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,2] then 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.