【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
null