poj1741树分治

来源:互联网 发布:mac yy语音进不了频道 编辑:程序博客网 时间:2024/05/16 18:50

第一次写树分治QAQ

var    a,b,n,k,i,l,cnt,tot : longint;e,cap,nx,ed,siz,dis : array[0..20000] of longint;vis : array[1..10000] of boolean;procedure sort(l,r:longint);var    i,j,mid,y : longint;begin    i := l; j := r; mid := dis[r];repeat    while dis[i] < mid do inc(i);while mid < dis[j] do dec(j);if i <= j thenbegin    y := dis[i]; dis[i] := dis[j]; dis[j] := y;    inc(i); dec(j);end;until i > j;if l < j then sort(l,j);if i < r then sort(i,r);end;procedure add(x,y,z:longint);begin    e[cnt] := y; cap[cnt] := z; nx[cnt] := ed[x]; ed[x] := cnt; inc(cnt);end;procedure dfssize(p,f:longint);var    i : longint;begin    i := ed[p]; siz[p] := 1;while i > -1 dobegin    if (e[i] <> f) and (not vis[e[i]]) thenbegin    dfssize(e[i],p); inc(siz[p],siz[e[i]]);end;i := nx[i];end;end;function getroot(p,f,s:longint):longint;var    i,max,c : longint;begin    i := ed[p]; max := 0;while i > -1 dobegin    if (e[i] <> f) and (not vis[e[i]]) then    if siz[e[i]] > max then    begin    max := siz[e[i]]; c := e[i];end;i := nx[i];end;if max << 1 <= s then exit(p) else exit(getroot(c,p,s));end;procedure dfsdis(p,f,d:longint);var    i : longint;begin    i := ed[p]; inc(tot); dis[tot] := d;while i > -1 dobegin    if (e[i] <> f) and (not vis[e[i]]) then dfsdis(e[i],p,d+cap[i]);i := nx[i];end;end;function calc(p,k:longint):longint;var    i,j : longint;begin    tot := 0; calc := 0; dfsdis(p,0,0); sort(1,tot); j := tot;for i := 1 to tot dobegin    while (j > 0) and (dis[i]+dis[j] > k) do dec(j);inc(calc,j-ord(i <= j));end;    calc := calc >> 1;end;function work(p,f:longint):longint;var    i,root : longint;begin    dfssize(p,f); root := getroot(p,f,siz[p]);vis[root] := true;work := calc(root,k);i := ed[root];while i > -1 dobegin    if not vis[e[i]] and (e[i] <> f) then dec(work,calc(e[i],k-cap[i] << 1));    i := nx[i];end;i := ed[root];while i > -1 dobegin    if not vis[e[i]] and (e[i] <> f) then inc(work,work(e[i],root));i := nx[i];end;end;begin    while true dobegin    readln(n,k);for i := 1 to n do ed[i] := -1; cnt := 0; fillchar(vis,sizeof(vis),0);if n = 0 then halt;for i := 1 to n-1 dobegin    readln(a,b,l);add(a,b,l); add(b,a,l);end;writeln(work(1,0));end;end.

0 0
原创粉丝点击