首页 > 代码库 > poj1741 Tree(点分治)

poj1741 Tree(点分治)

Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001). 
Define dist(u,v)=The min distance between node u and v. 
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k. 
Write a program that will count how many pairs which are valid for a given tree. 

Input

The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l. 
The last test case is followed by two zeros. 

Output

For each test case output the answer on a single line.

Sample Input

5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0

Sample Output

8


题目大意:

给定一棵N个结点的带权树。 定义dist(u,v)=u,v两点间的路径长度,路径的长度定义为路径上所有边的权和。 给定一个K,如果对于不同的两个结点a,b,如果满足dist(a,b)≤K,则称(a,b)为合法点对。 求合法点对个数。


这道题是点分治的模板题,具体可参考2009年漆子超的国家集训队论文《分治算法在树的路径问题中的应用》
第一次写点分治,非常不熟练,也犯了一些变量打错的sb错误。
AC代码:
  1 program rrr(input,output);
  2 type
  3   etype=record
  4      t,l,next:longint;
  5   end;
  6 var
  7   e:array[0..20020]of etype;
  8   a,q,father,siz,f,w:array[0..10010]of longint;
  9   v:array[0..10010]of boolean;
 10   n,m,i,min,x,y,l,cnt,r,h,t,ans:longint;
 11 procedure add(x,y,l:longint);
 12 begin
 13    inc(cnt);e[cnt].t:=y;e[cnt].l:=l;e[cnt].next:=a[x];a[x]:=cnt;
 14 end;
 15 function max(a,b:longint):longint;
 16 begin
 17    if a>b then exit(a) else exit(b);
 18 end;
 19 procedure sort(q,h:longint);
 20 var
 21   i,j,x,t:longint;
 22 begin
 23    i:=q;j:=h;x:=w[(i+j)>>1];
 24    repeat
 25      while w[i]<x do inc(i);
 26      while x<w[j] do dec(j);
 27      if i<=j then
 28         begin
 29            t:=w[i];w[i]:=w[j];w[j]:=t;
 30            inc(i);dec(j);
 31         end;
 32    until i>j;
 33    if j>q then sort(q,j);
 34    if i<h then sort(i,h);
 35 end;
 36 function sum(h,t:longint):longint;
 37 var
 38   i,j,ans:longint;
 39 begin
 40    sort(h,t);
 41    ans:=0;j:=t;
 42    for i:=h to t do
 43       begin
 44          while (w[i]+w[j]>m) and (j>i) do dec(j);
 45          if i=j then break;
 46          ans:=ans+j-i;
 47       end;
 48    exit(ans);
 49 end;
 50 procedure solve(k:longint);
 51 var
 52   i,j:longint;
 53 begin
 54    h:=0;t:=1;q[1]:=k;father[k]:=0;
 55    while h<t do
 56       begin
 57          inc(h);
 58          i:=a[q[h]];
 59          while i<>0 do
 60             begin
 61                if not v[e[i].t] and (e[i].t<>father[q[h]]) then
 62                   begin
 63                      father[e[i].t]:=q[h];
 64                      inc(t);q[t]:=e[i].t;
 65                   end;
 66                i:=e[i].next;
 67             end;
 68       end;
 69    if t=1 then exit;
 70    for i:=1 to t do begin siz[q[i]]:=1;f[q[i]]:=0; end;
 71    min:=n;
 72    for i:=t downto 2 do
 73       begin
 74          r:=max(f[q[i]],t-siz[q[i]]);
 75          if r<min then begin min:=r;j:=q[i]; end;
 76          inc(siz[father[q[i]]],siz[q[i]]);
 77          if siz[q[i]]>f[father[q[i]]] then f[father[q[i]]]:=siz[q[i]];
 78       end;
 79    if f[k]<min then j:=k;
 80    r:=a[j];cnt:=0;
 81    while r<>0 do
 82       begin
 83          if not v[e[r].t] then
 84             begin
 85                h:=0;t:=1;q[1]:=e[r].t;father[e[r].t]:=j;w[cnt+1]:=e[r].l;
 86                while h<t do
 87                   begin
 88                      inc(h);
 89                      i:=a[q[h]];
 90                      while i<>0 do
 91                         begin
 92                            if not v[e[i].t] and (e[i].t<>father[q[h]]) then
 93                               begin
 94                                  father[e[i].t]:=q[h];
 95                                  inc(t);q[t]:=e[i].t;w[cnt+t]:=w[cnt+h]+e[i].l;
 96                               end;
 97                            i:=e[i].next;
 98                         end;
 99                   end;
100                ans:=ans-sum(cnt+1,cnt+t);
101                cnt:=cnt+t;
102             end;
103          r:=e[r].next;
104       end;
105    inc(cnt);w[cnt]:=0;
106    ans:=ans+sum(1,cnt);
107    v[j]:=true;i:=a[j];
108    while i<>0 do begin if not v[e[i].t] then solve(e[i].t);i:=e[i].next; end;
109 end;
110 begin
111    assign(input,r.in);assign(output,r.out);reset(input);rewrite(output);
112    while true do
113       begin
114          read(n,m);if (n=0) and (m=0) then break;
115          for i:=1 to n do a[i]:=0;cnt:=0;
116          for i:=1 to n-1 do begin readln(x,y,l);add(x,y,l);add(y,x,l); end;
117          ans:=0;
118          for i:=1 to n do v[i]:=false;
119          solve(1);
120          writeln(ans);
121       end;
122    close(input);close(output);
123 end.

 

 

poj1741 Tree(点分治)