题意:小C上周末和他可爱的同学小A一起去X湖玩。
X湖景区一共有n个景点,这些景点由n-1条观光道连接着,从每个景点开始都可以通过观光道直接或间接地走到其他所有的景点。小C带着小A从1号景点开始游玩。游览完第一个景点后,先由小C决定下一个游览的景点,他们一起走去那个景点玩。接下来,他们轮流决定他们下一步去哪个景点玩。他们不会选择已经走过的景点,因为重复游览一个景点是无趣的。当他们无法选择下一个景点时,他们就结束旅程。
小C是好动的男孩纸,所以他希望游览的过程尽量长,也就是走过观光道的长度和最大。而小A是文静的女孩纸,她希望游览的过程尽量短。小A和小C都极度聪明,且他们的目光都足够长远,他们做出的决策都是对自己最优的。由于小C在旅游前就仔细研究了X湖景区的地图,他可以在旅行开始前就用自己惊人的数学能力推算出他和小A旅行的路径长度。
小C的梦境是美好的。在他的梦里,他和小A又进行了n-1次旅行,第i次旅行从i+1号点开始,每次也是小C先决定下一个景点,然后小A,然后小C……直到旅行结束。现在小C希望你对于所有n次旅行,求出他和小A旅行的路径长度。
对于100%的数据,N ≤ 300000, c[i] ≤ 1e9
对于60%的数据,N ≤ 3000
思路:对于60分,容易想到枚举根,做N次O(N)的DP,时间复杂度O(n)
对于100分,模拟样例后发现两个直接相连的节点U与V,其DP值只有U与V点时不同,所以考虑当根从U到V时O(1)转移求出新的DP[u]与DP[v]
注意此处不需要保证整个DP数组值都为正确,只要U的值与V的值正确即可
可以想到当U的最值由V转移时,两者交换后V必须从U的另一支转移,所以记录次值
调参大法好
1 var f:array[1..300000,1..4]of int64; 2 ans:array[1..300000]of int64; 3 head,vet,next,len,flag:array[1..600000]of longint; 4 n,tot,i,x,y,z:longint; 5 oo:int64; 6 7 procedure add(a,b,c:longint); 8 begin 9 inc(tot); 10 next[tot]:=head[a]; 11 vet[tot]:=b; 12 len[tot]:=c; 13 head[a]:=tot; 14 end; 15 16 procedure dfs(u:longint); 17 var e,v,de:longint; 18 t:int64; 19 begin 20 flag[u]:=1; 21 e:=head[u]; 22 de:=0; 23 while e<>0 do 24 begin 25 v:=vet[e]; 26 if flag[v]=0 then 27 begin 28 dfs(v); inc(de); 29 t:=f[v,3]+len[e]; 30 if (t>f[u,1])or(f[u,1]=0) then 31 begin 32 f[u,2]:=f[u,1]; f[u,1]:=t; 33 end 34 else if (t<=f[u,1])and(t>f[u,2])or(f[u,2]=0) then f[u,2]:=t; 35 36 t:=f[v,1]+len[e]; 37 if (t<f[u,3])or(f[u,3]=0) then 38 begin 39 f[u,4]:=f[u,3]; f[u,3]:=t; 40 end 41 else if (t>=f[u,3])and(t<f[u,4])or(f[u,4]=0) then f[u,4]:=t; 42 43 end; 44 e:=next[e]; 45 end; 46 47 end; 48 49 procedure change(u:longint); 50 var e,v:longint; 51 t,t1,t2,t3,t4:int64; 52 begin 53 e:=head[u]; flag[u]:=1; 54 t1:=f[u,1]; t2:=f[u,2]; t3:=f[u,3]; t4:=f[u,4]; 55 56 ans[u]:=f[u,1]; 57 while e<>0 do 58 begin 59 v:=vet[e]; 60 61 if flag[v]=1 then begin e:=next[e]; continue; end; 62 if f[v,3]+len[e]=t1 then t:=f[u,2]+len[e] 63 else t:=f[u,1]+len[e]; 64 if (t<f[v,3])or(f[v,3]=0) then 65 begin 66 f[v,4]:=f[v,3]; f[v,3]:=t; 67 end 68 else if (t<f[v,4])or(f[v,4]=0) then f[v,4]:=t; 69 70 if f[v,1]+len[e]=t3 then begin t:=f[u,4]+len[e];end 71 else t:=f[u,3]+len[e]; 72 73 74 if (t>f[v,1])or(f[v,1]=0) then 75 begin 76 f[v,2]:=f[v,1]; f[v,1]:=t; 77 end 78 else if (t>f[v,2])or(f[v,2]=0) then f[v,2]:=t; 79 change(v); 80 e:=next[e]; 81 end; 82 83 84 end; 85 86 begin 87 assign(input,'travel.in'); reset(input); 88 assign(output,'travel.out'); rewrite(output); 89 oo:=1<<63; 90 readln(n); //f[u,1]zuida f[u,2]cida 91 //f[u,3]zuixiao f[u,4]cixiao 92 for i:=1 to n-1 do 93 begin 94 readln(x,y,z); 95 add(x,y,z); 96 add(y,x,z); 97 end; 98 99 dfs(1); 100 fillchar(flag,sizeof(flag),0); 101 change(1); 102 for i:=1 to n do writeln(ans[i]); 103 close(input); 104 close(output); 105 end.