Poj_1741_Tree

Posted zyx-crying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Poj_1741_Tree相关的知识,希望对你有一定的参考价值。

Description

给一个有n个顶点的树,每个边都有一个长度(正整数小于1001)。
定义dist(u,v)=节点u和v之间的最小距离。
给出一个整数k,当且仅当dist(u,v)不超过k时,每个对(u,v)的顶点都被称为有效。
编写一个程序,计算对给定树有效的对数。

 

Input

输入包含几个测试用例。 每个测试用例的第一行包含两个整数n,k。 (n <= 10000)以下n-1行各包含三个整数u,v,l,这意味着在节点u和v之间存在长度为l的边。
最后一个测试用例后跟两个零。

 

Output

对于每个测试用例,在单行上输出答案。

 

Solution

裸的点分。

细节:注意不能同一个子树的对数不能算。

 
代码
  1 type
  2   arr=record
  3     y,w,next:longint;
  4   end;
  5 var
  6   n,s,e,nm,dt,ans,min:longint;
  7   a:array [0..200001] of arr;
  8   ls,size,v,d,deep:array [0..100001] of longint;
  9 procedure add(x,y,z:longint);
 10 begin
 11   inc(nm);
 12   a[nm].y:=y; a[nm].w:=z;
 13   a[nm].next:=ls[x]; ls[x]:=nm;
 14 end;
 15 
 16 procedure init;
 17 var
 18   i,x,y,z:longint;
 19 begin
 20   nm:=0;
 21   for i:=1 to n-1 do
 22     begin
 23       readln(x,y,z);
 24       add(x,y,z); add(y,x,z);
 25     end;
 26   ans:=0;
 27 end;
 28 
 29 procedure dfs1(x,last:longint);
 30 var
 31   i:longint;
 32 begin
 33   size[x]:=1; i:=ls[x];
 34   while i<>0 do
 35     begin
 36       if (v[a[i].y]=1) or (a[i].y=last) then
 37         begin
 38           i:=a[i].next;
 39           continue;
 40         end;
 41       dfs1(a[i].y,x);
 42       size[x]:=size[x]+size[a[i].y];
 43       i:=a[i].next;
 44     end;
 45 end;
 46 
 47 function dfs2(x,last,tot:longint):longint;
 48 var
 49   i:longint;
 50 begin
 51   i:=ls[x];
 52   while i<>0 do
 53     begin
 54       if (v[a[i].y]=1) or (a[i].y=last) or (size[a[i].y]*2<tot) then
 55         begin
 56           i:=a[i].next;
 57           continue;
 58         end;
 59       exit(dfs2(a[i].y,x,tot));
 60       i:=a[i].next;
 61     end;
 62   exit(x);
 63 end;
 64 
 65 procedure gd(x,last:longint);
 66 var
 67   i:longint;
 68 begin
 69   inc(dt); d[dt]:=deep[x];
 70   i:=ls[x];
 71   while i<>0 do
 72     begin
 73       if (a[i].y=last) or (v[a[i].y]=1) then
 74         begin
 75           i:=a[i].next;
 76           continue;
 77         end;
 78       deep[a[i].y]:=deep[x]+a[i].w;
 79       gd(a[i].y,x);
 80       i:=a[i].next;
 81     end;
 82 end;
 83 
 84 procedure qsort(l,r:longint);
 85 var
 86   mid,i,j,k:longint;
 87 begin
 88   if l>r then exit;
 89   i:=l; j:=r;
 90   mid:=d[(l+r) div 2];
 91   repeat
 92     while d[i]<mid do inc(i);
 93     while d[j]>mid do dec(j);
 94     if i<=j then
 95       begin
 96         k:=d[i]; d[i]:=d[j]; d[j]:=k;
 97         inc(i); dec(j);
 98       end;
 99   until i>j;
100   qsort(i,r);
101   qsort(l,j);
102 end;
103 
104 function js(x,cz:longint):longint;
105 var
106   i,j,num:longint;
107 begin
108   num:=0;
109   dt:=0; deep[x]:=cz;
110   gd(x,0);
111   qsort(1,dt);
112   j:=dt; i:=1;
113   while i<j do
114     if (d[i]+d[j]<=e) then
115       begin
116         num:=num+j-i;
117         inc(i);
118       end else dec(j);
119   exit(num);
120 end;
121 
122 procedure main(x:longint);
123 var
124   i:longint;
125 begin
126   ans:=ans+js(x,0);
127   v[x]:=1;
128   i:=ls[x];
129   while i<>0 do
130 
131     begin
132       if v[a[i].y]=1 then
133         begin
134           i:=a[i].next;
135           continue;
136         end;
137       ans:=ans-js(a[i].y,a[i].w);
138       dfs1(a[i].y,0);
139       main(dfs2(a[i].y,0,size[a[i].y]));
140       i:=a[i].next;
141     end;
142 end;
143 
144 begin
145   readln(n,e);
146   while (n<>0) and (e<>0) do
147     begin
148       fillchar(ls,sizeof(ls),0);
149       fillchar(v,sizeof(v),0);
150       init;
151       dfs1(1,0);
152       main(dfs2(1,0,n));
153       write(ans);
154       readln(n,e);
155     end;
156 end.

 

以上是关于Poj_1741_Tree的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1741 Tree ——(树分治)

Tree POJ - 1741

poj1741 Tree(点分治)

●POJ 1741 Tree

POJ 1741 Tree ——点分治

POJ 1741 Tree