• 【POJ1741】Tree(点分治)


    题意:

    思路:点分治论文题

    我们知道一条路径要么过根结点,要么在一棵子树中,这启发了我们可以使用分治算法。

    记 Depth(i)表示点i 到根结点的路径长度, Belong(i) = X ( X 为根结点的某个儿子,且结点i 在以 X 为根的子树内)。

    那么我们要统计的就是:

    满足 Depth (i) + Depth ( j)<= K 且 Belong(i) <>Belong(j) 的 (i, j) 个

    = 满足 Depth(i) +Depth( j) <= K 的 (i, j) 个数

    – 满足 Depth(i) + Depth( j) <= K 且 Belong(i) =Belong( j)的 (i, j) 个数

    而对于这两个部分,都是要求出满足 Ai+Aj <= k 的(i, j) 的对数。

    将 A 排序后利用单调性我们很容易得出一个O(N) 的算法,所以我们

    可以用O(N log N)的时间来解决这个问题。

    综上,此题使用树的分治算法时间复杂度为O(N log^2 N) 。 

      1 var head,vet,next,len,son,flag,d:array[1..50000]of longint;
      2     dep,f:array[0..50000]of longint;
      3     n,m,i,x,y,z,tot,ans,sum,root,k:longint;
      4 
      5 procedure swap(var x,y:longint);
      6 var t:longint;
      7 begin
      8  t:=x; x:=y; y:=t;
      9 end;
     10 
     11 procedure add(a,b,c:longint);
     12 begin
     13  inc(tot);
     14  next[tot]:=head[a];
     15  vet[tot]:=b;
     16  len[tot]:=c;
     17  head[a]:=tot;
     18 end;
     19 
     20 function max(x,y:longint):longint;
     21 begin
     22  if x>y then exit(x);
     23  exit(y);
     24 end;
     25 
     26 procedure getroot(u,fa:longint);
     27 var e,v:longint;
     28 begin
     29  son[u]:=1; f[u]:=0;
     30  e:=head[u];
     31  while e<>0 do
     32  begin
     33   v:=vet[e];
     34   if (v<>fa)and(flag[v]=0) then
     35   begin
     36    getroot(v,u);
     37    son[u]:=son[u]+son[v];
     38    f[u]:=max(f[u],son[v]);
     39   end;
     40   e:=next[e];
     41  end;
     42  f[u]:=max(f[u],sum-f[u]);
     43  if f[u]<f[root] then root:=u;
     44 end;
     45 
     46 procedure getdeep(u,fa:longint);
     47 var e,v:longint;
     48 begin
     49  inc(dep[0]); dep[dep[0]]:=d[u];
     50  e:=head[u];
     51  while e<>0 do
     52  begin
     53   v:=vet[e];
     54   if (v<>fa)and(flag[v]=0) then
     55   begin
     56    d[v]:=d[u]+len[e];
     57    getdeep(v,u);
     58   end;
     59   e:=next[e];
     60  end;
     61 end;
     62 
     63 procedure qsort(l,r:longint);
     64 var i,j,mid:longint;
     65 begin
     66  i:=l; j:=r; mid:=dep[(l+r)>>1];
     67  repeat
     68   while mid>dep[i] do inc(i);
     69   while mid<dep[j] do dec(j);
     70   if i<=j then
     71   begin
     72    swap(dep[i],dep[j]);
     73    inc(i); dec(j);
     74   end;
     75  until i>j;
     76  if l<j then qsort(l,j);
     77  if i<r then qsort(i,r);
     78 end;
     79 
     80 function clac(u,now:longint):longint;
     81 var l,r:longint;
     82 begin
     83  d[u]:=now; dep[0]:=0;
     84  getdeep(u,0);
     85  qsort(1,dep[0]);
     86  clac:=0;
     87  l:=1; r:=dep[0];
     88  while l<r do
     89  begin
     90   if dep[l]+dep[r]<=k then begin clac:=clac+r-l; inc(l); end
     91    else dec(r);
     92  end;
     93 end;
     94 
     95 procedure work(u:longint);
     96 var e,v:longint;
     97 begin
     98  ans:=ans+clac(u,0);
     99  flag[u]:=1;
    100  e:=head[u];
    101  while e<>0 do
    102  begin
    103   v:=vet[e];
    104   if flag[v]=0 then
    105   begin
    106    ans:=ans-clac(v,len[e]);
    107    sum:=son[v];
    108    root:=0;
    109    getroot(v,root);
    110    work(root);
    111   end;
    112   e:=next[e];
    113  end;
    114 end;
    115 
    116 begin
    117  assign(input,'poj1741.in'); reset(input);
    118  assign(output,'poj1741.out'); rewrite(output);
    119  while not eof do
    120  begin
    121   fillchar(head,sizeof(head),0);
    122   fillchar(flag,sizeof(flag),0);
    123   tot:=0;
    124   readln(n,k);
    125   if (n=0)and(m=0) then break;
    126   for i:=1 to n-1 do
    127   begin
    128    readln(x,y,z);
    129    add(x,y,z);
    130    add(y,x,z);
    131   end;
    132   sum:=n; f[0]:=maxlongint; ans:=0;
    133   getroot(1,0);
    134   work(root);
    135   writeln(ans);
    136  end;
    137  close(input);
    138  close(output);
    139 end.
  • 相关阅读:
    地铁线路问题分析
    软件工程大作业(社团管理系统)-个人总结报告
    第九组_社团管理系统_原型相关文档
    北京地铁线路出行和规划
    地铁线路规划
    WC 个人项目 ( node.js 实现 )
    自我介绍 + 软工5问
    软工个人项目(Java实现)
    自我介绍+软工五问
    结对编程(前后端分离)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6518176.html
Copyright © 2020-2023  润新知