【NOIP模拟&POJ2152】灰色的果实(树形DP)

题意:

Nebula 历 2014 年 12 月 17 日,欢迎来到异世界。
面对截然不同的新世界,你决定采取最普通但最为有效的方式来探索,那便
是徒步。准备好营地的一切,你开始了探索的旅程。
步行大约 10 分钟的路程,穿过森林,你来到了一个悬崖,极目远眺,你看
见了梦幻般的光景。 一棵高大的无法用言语描述的数耸立于悬崖的对岸, 其冠直
冲云天, 其根深入地下。 而这棵大树,最引人瞩目的就是结于其枝上的两颗灰色
的果实。
忽然,古老而悠远的声音传入你的脑海之中: “掌握未来之人必先经过命运
的磨练。拥有‘未来视’受命运牵引前来的人类啊,在这个万华镜的世界,一共
有三个关卡,逐一通过考验之后, 前进之道路将会展现于你的面前。第一个考验
规则写于旁边的牌子,详情请参阅。”
你将目光转向一旁的木牌。上书道:
此树为灰色果实之树,不定时会长出灰色果实。贸然接近果实只会使得自己受其迷惑最后神经错乱而
浑浑噩噩不得终日,与死人无异。你的目标是成功到达树的顶端,砍下灰色果实的灵脉。
为了能够免除灰色果实的影响, 你需要在灰色果实力量微弱时在树的各个点
设置若干个保护点, 保护点内燃烧着镇定人心的香,以此来抵御灰色果实的精神
袭击。一个点必须在 lim[i]距离以内有保护点才能收到保护。而且,由于在树上
作业,地形十分崎岖,使得不同点设置保护点的作业时间 time[i]不同。
谋求最大的效率,请求出保护点笼罩整棵树所需的最短作业时间
 
思路:2006国家集训队陈启峰论文题
dp[u,i]为以u为根的子树全部被i保护的总代价
f[u]为以u为根的子树全部被保护的最小总代价
 1 var dp,dis:array[1..2100,1..2100]of longint;
 2     q:array[0..100000]of longint;
 3     head,vet,next,len,f,flag,time,lim:array[1..10000]of longint;
 4     inq:array[1..10000]of boolean;
 5     n,i,tot,x,y,z:longint;
 6  
 7 function min(x,y:longint):longint;
 8 begin
 9  if x<y then exit(x);
10  exit(y);
11 end;
12  
13 procedure add(a,b,c:longint);
14 begin
15  inc(tot);
16  next[tot]:=head[a];
17  vet[tot]:=b;
18  len[tot]:=c;
19  head[a]:=tot;
20 end;
21  
22 procedure spfa(st:longint);
23 var t,w,u,e,v:longint;
24 begin
25  fillchar(inq,sizeof(inq),false);
26  t:=0; w:=0; q[0]:=st; dis[st,st]:=0; inq[st]:=true;
27  while t<=w do
28  begin
29   u:=q[t]; inc(t); inq[u]:=false;
30   e:=head[u];
31   while e<>0 do
32   begin
33    v:=vet[e];
34    if dis[st,u]+len[e]<dis[st,v] then
35    begin
36     dis[st,v]:=dis[st,u]+len[e];
37     if not inq[v] then
38     begin
39      inc(w); q[w]:=v; inq[v]:=true;
40     end;
41    end;
42    e:=next[e];
43   end;
44  end;
45 end;
46  
47  
48 procedure dfs(u,fa:longint);
49 var e,v,i:longint;
50 begin
51  e:=head[u];
52  while e<>0 do
53  begin
54   v:=vet[e];
55   if v<>fa then dfs(v,u);
56   e:=next[e];
57  end;
58  for i:=1 to n do
59   if dis[u,i]<=lim[u] then
60   begin
61    dp[u,i]:=0;
62    e:=head[u];
63    while e<>0 do
64    begin
65     v:=vet[e];
66     if v<>fa then dp[u,i]:=dp[u,i]+min(dp[v,i]-time[i],f[v]);
67     e:=next[e];
68    end;
69    dp[u,i]:=dp[u,i]+time[i];
70    f[u]:=min(f[u],dp[u,i]);
71   end;
72 end;
73  
74 begin
75  
76  
77  readln(n);
78  for i:=1 to n do read(time[i]);
79  for i:=1 to n do read(lim[i]);
80  for i:=1 to n-1 do
81  begin
82   readln(x,y,z);
83   add(x,y,z);
84   add(y,x,z);
85  end;
86  fillchar(dp,sizeof(dp),$3f);
87  fillchar(f,sizeof(f),$3f);
88  fillchar(dis,sizeof(dis),$3f);
89  for i:=1 to n do spfa(i);
90  dfs(1,0);
91  writeln(f[1]);
92  
93  
94 end.
95  
 

猜你喜欢

转载自www.cnblogs.com/myx12345/p/9317405.html
今日推荐