幸福的道路

有一棵树,求出以每个点为起点的最长路径长度后,找到最长的连续区间满足极差不超过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.
posted @ 2012-04-15 19:45  Codinginging  阅读(248)  评论(0编辑  收藏  举报