1602: [Usaco2008 Oct]牧场行走
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 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
2 1 2
4 3 2
1 4 3
1 2
3 2
Sample Output
2
7
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.