zoukankan      html  css  js  c++  java
  • 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.
    
    
    
     
  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/Currier/p/6517494.html
Copyright © 2011-2022 走看看