BZOJ1602: [Usaco2008 Oct]牧场行走

1602: [Usaco2008 Oct]牧场行走

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1084  Solved: 556
[Submit][Status]

Description

N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000)。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况,所以说这是一棵树。 这些奶牛是非常喜欢交际的,经常会去互相访问,他们想让你去帮助他们计算Q(1<=q<=1000)对奶牛之间的距离。

Input

*第一行:两个被空格隔开的整数:N和Q

 *第二行到第n行:第i+1行有两个被空格隔开的整数:AI,BI,LI

*第n+1行到n+Q行:每一行有两个空格隔开的整数:P1,P2,表示两头奶牛的编号。

Output

*第1行到第Q行:每行输出一个数,表示那两头奶牛之间的距离。

Sample Input

4 2
2 1 2
4 3 2
1 4 3
1 2
3 2

Sample Output

2
7

HINT

 

Source

题解:
不想写倍增了,把树链剖分的代码贴上改了改就A了。。。
每个节点保存的是到父亲的距离,所以对LCA要特判
代码:
  1 const maxn=1000+100;
  2 type node1=record
  3      go,next,z:longint;
  4      end;
  5      node2=record
  6      l,r,mid,sum:longint;
  7      end;
  8 
  9 var  e:array[0..2*maxn] of node1;
 10      t:array[0..4*maxn] of node2;
 11      p,a,v,fa,s,head,dep,son,top:array[0..maxn] of longint;
 12      i,n,m,x,y,z,sz,ans,tot:longint;
 13      ch:char;
 14      procedure swap(var x,y:longint);
 15       var t:longint;
 16       begin
 17         t:=x;x:=y;y:=t;
 18       end;
 19      procedure insert(x,y,z:longint);
 20       begin
 21         inc(tot);
 22         e[tot].go:=y;e[tot].z:=z;e[tot].next:=head[x];head[x]:=tot;
 23       end;
 24      function min(x,y:longint):longint;
 25       begin
 26         if x<y then exit(x) else exit(y);
 27       end;
 28      function max(x,y:longint):longint;
 29       begin
 30         if x>y then exit(x) else exit(y);
 31       end;
 32 
 33 procedure dfs1(x:longint);
 34  var i,j,y:longint;
 35  begin
 36    j:=0;s[x]:=1;
 37    i:=head[x];
 38    while i<>0 do
 39     begin
 40      y:=e[i].go;
 41      if dep[y]=0 then
 42       begin
 43         dep[y]:=dep[x]+1;
 44         fa[y]:=x;v[y]:=e[i].z;
 45         dfs1(y);
 46         inc(s[x],s[y]);
 47         if s[y]>s[j] then j:=y;
 48       end;
 49      i:=e[i].next;
 50     end;
 51    son[x]:=j;
 52  end;
 53 procedure dfs2(x,chain:longint);
 54  var i,y:longint;
 55  begin
 56    inc(sz);p[x]:=sz;top[x]:=chain;
 57    if son[x]<>0 then dfs2(son[x],chain);
 58    i:=head[x];
 59    while i<>0 do
 60      begin
 61       y:=e[i].go;
 62       if (p[y]=0) and (y<>son[x]) then dfs2(y,y);
 63       i:=e[i].next;
 64      end;
 65  end;
 66 procedure pushup(k:longint);
 67  begin
 68     t[k].sum:=t[k<<1].sum+t[k<<1+1].sum;
 69  end;
 70 
 71 procedure build(k,x,y:longint);
 72  begin
 73    with t[k] do
 74     begin
 75      l:=x;r:=y;mid:=(l+r)>>1;
 76      if l=r then begin sum:=a[l];exit;end;
 77      build(k<<1,l,mid);build(k<<1+1,mid+1,r);
 78      pushup(k);
 79     end;
 80  end;
 81 function getsum(k,x,y:longint):longint;
 82  begin
 83    with t[k] do
 84     begin
 85      if (l=x) and (r=y) then exit(sum);
 86      if y<=mid then exit(getsum(k<<1,x,y))
 87      else if x>mid then exit(getsum(k<<1+1,x,y))
 88      else exit(getsum(k<<1,x,mid)+getsum(k<<1+1,mid+1,y));
 89     end;
 90  end;
 91 procedure init;
 92  begin
 93    readln(n,m);
 94    for i:=1 to n-1 do begin readln(x,y,z);insert(x,y,z);insert(y,x,z);end;
 95    dep[1]:=1;
 96    dfs1(1);
 97    dfs2(1,1);
 98    for i:=2 to n do a[p[i]]:=v[i];
 99    build(1,1,n);
100  end;
101 procedure solvesum;
102  begin
103    ans:=0;
104    readln(x,y);
105      while top[x]<>top[y] do
106      begin
107       if dep[top[x]]<dep[top[y]] then swap(x,y);
108       inc(ans,getsum(1,p[top[x]],p[x]));
109       x:=fa[top[x]];
110      end;
111    if dep[x]>dep[y] then swap(x,y);
112    inc(ans,getsum(1,p[x],p[y]));
113    if p[x]<>1 then dec(ans,v[x]);
114    writeln(ans);
115  end;
116 
117 procedure main;
118  begin
119    for i:=1 to m do solvesum;
120  end;
121 
122 begin
123   assign(input,'input.txt');assign(output,'output.txt');
124   reset(input);rewrite(output);
125   init;
126   main;
127   close(input);close(output);
128 end.                                             
View Code

 

 
posted @ 2014-08-11 23:05  ZYF-ZYF  Views(159)  Comments(0Edit  收藏  举报