幸福的道路
有一棵树,求出以每个点为起点的最长路径长度后,找到最长的连续区间满足极差不超过M。
有一个重要的性质,一个点为起点的最长路的终点一定是直径的某个端点,问题转换为直径,O(n)
之后ST处理出区间最值O(nlogn)
用类似队列的维护形式求最长区间 O(n)
View Code
1 {$inline on} 2 {$M 10000000000} 3 program race(input,output); 4 type 5 node = ^link; 6 link = record 7 goal,w : longint; 8 next : node; 9 end; 10 const 11 oo = maxlongint>>1; 12 var 13 f,g : array[0..1000100,0..20] of longint; 14 l : array[0..1000100] of node; 15 dx,dy : array[0..1000100] of longint; 16 start,endd : longint; 17 n,m : longint; 18 answer : longint; 19 function max(aa,bb :longint ):longint; inline; 20 begin 21 if aa>bb then 22 exit(aa); 23 exit(bb); 24 end; { max } 25 function min(aa,bb :longint ):longint; inline; 26 begin 27 if aa<bb then 28 exit(aa); 29 exit(bb); 30 end; { min } 31 procedure add(xx,yy,ww: longint ); inline; 32 var 33 tt : node; 34 begin 35 new(tt); 36 tt^.goal:=yy; 37 tt^.w:=ww; 38 tt^.next:=l[xx]; 39 l[xx]:=tt; 40 end; { add } 41 procedure init; inline; 42 var 43 i,xx,yy : longint; 44 begin 45 readln(n,m); 46 for i:=2 to n do 47 begin 48 readln(xx,yy); 49 add(i,xx,yy); 50 add(xx,i,yy); 51 end; 52 end; { init } 53 procedure dfs1(now,dist : longint ); inline; 54 var 55 t : node; 56 begin 57 dx[now]:=dist; 58 t:=l[now]; 59 while t<>nil do 60 begin 61 if dx[t^.goal]=-1 then 62 dfs1(t^.goal,dist+t^.w); 63 t:=t^.next; 64 end; 65 end; { dfs1 } 66 procedure dfs2(now,dist :longint ); inline; 67 var 68 t : node; 69 begin 70 dy[now]:=dist; 71 t:=l[now]; 72 while t<>nil do 73 begin 74 if dy[t^.goal]=-1 then 75 dfs2(t^.goal,dist+t^.w); 76 t:=t^.next; 77 end; 78 end; { dfs2 } 79 procedure previous; inline; 80 var 81 i : longint; 82 maxl : int64; 83 begin 84 for i:=1 to n do 85 dx[i]:=-1; 86 dfs1(1,0); 87 maxl:=0; 88 for i:=1 to n do 89 if dx[i]>maxl then 90 begin 91 start:=i; 92 maxl:=dx[i]; 93 end; 94 for i:=1 to n do 95 dx[i]:=-1; 96 dfs1(start,0); 97 maxl:=0; 98 for i:=1 to n do 99 if dx[i]>maxl then 100 begin 101 maxl:=dx[i]; 102 endd:=i; 103 end; 104 for i:=1 to n do 105 dy[i]:=-1; 106 dfs2(endd,0); 107 for i:=1 to n do 108 if dy[i]>dx[i] then 109 dx[i]:=dy[i]; 110 end; { previous } 111 procedure ST(); inline; 112 var 113 i,j : longint; 114 begin 115 for i:=1 to n do 116 begin 117 f[i,0]:=dx[i]; 118 g[i,0]:=dx[i]; 119 end; 120 for j:=1 to trunc(ln(n)/ln(2)) do 121 for i:=1 to n do 122 if i+1<<(j-1)>n then 123 break 124 else 125 begin 126 f[i,j]:=min(f[i,j-1],f[i+1<<(j-1),j-1]); 127 g[i,j]:=max(g[i,j-1],g[i+1<<(j-1),j-1]); 128 end; 129 end; { ST } 130 procedure solve(); inline; 131 var 132 head,tail,i,t : longint; 133 maxx,minx : longint; 134 begin 135 head:=1; 136 tail:=0; 137 maxx:=-oo; 138 minx:=oo; 139 answer:=0; 140 for i:=1 to n do 141 begin 142 inc(tail); 143 if dx[i]>maxx then 144 maxx:=dx[i]; 145 if dx[i]<minx then 146 minx:=dx[i]; 147 while (maxx-minx>m)and(tail>head) do 148 begin 149 inc(head); 150 t:=trunc(ln(tail-head+1)/ln(2)); 151 maxx:=max(g[head,t],g[tail-1<<t+1,t]); 152 minx:=min(f[head,t],f[tail-1<<t+1,t]); 153 end; 154 if tail-head+1>answer then 155 answer:=tail-head+1; 156 end; 157 end; { solve } 158 procedure print; inline; 159 var 160 i : longint; 161 begin 162 writeln(answer); 163 end; { print } 164 begin 165 assign(input,'race.in');reset(input); 166 assign(output,'race.out');rewrite(output); 167 init; 168 previous; 169 st(); 170 solve(); 171 print; 172 close(input); 173 close(output); 174 end.