实现的功能如下——在一个N个点的无环图中,共有N-1条边,M个访问中每次询问两个点的距离
原理——既然N个点,N-1条边,则说明这是一棵树,而且联通。所以以1为根节点DFS建树,然后通过求两点的LCA的方式,先求得最近公共祖先,然后再通过深度来求出两点距离
1 type
2 point=^node;
3 node=record
4 g:longint;
5 next:point;
6 end;
7 const
8 maxn=100500;
9 maxm=trunc(ln(maxn)/ln(2))+1;
10 var
11 i,j,k,l,m,n:longint;
12 a:array[0..maxn] of point;
13 c:array[0..maxm,0..maxn] of longint;
14 d:array[0..maxn] of longint;
15 function max(x,y:longint):longint;inline;
16 begin
17 if x>y then max:=x else max:=y;
18 end;
19 function min(x,y:longint):longint;inline;
20 begin
21 if x<y then min:=x else min:=y;
22 end;
23 procedure swap(var x,y:longint);inline;
24 var z:longint;
25 begin
26 z:=x;x:=y;y:=z;
27 end;
28 procedure add(x,y:longint);inline;
29 var p:point;
30 begin
31 new(p);p^.g:=y;
32 p^.next:=a[x];a[x]:=p;
33 end;
34 procedure dfs(x:longint);inline;
35 var p:point;
36 begin
37 p:=a[x];
38 while p<>nil do
39 begin
40 if c[0,p^.g]=0 then
41 begin
42 c[0,p^.g]:=x;
43 d[p^.g]:=d[x]+1;
44 dfs(p^.g);
45 end;
46 p:=p^.next;
47 end;
48 end;
49 function getfat(x,y:longint):longint;inline;
50 var i,j,k:longint;
51 begin
52 i:=0;
53 while y>0 do
54 begin
55 if odd(y) then x:=c[i,x];
56 inc(i);y:=y div 2;
57 end;
58 exit(x);
59 end;
60 function getcom(x,y:longint):longint;inline;
61 var i:longint;
62 begin
63 if d[x]<d[y] then swap(x,y);
64 x:=getfat(x,d[x]-d[y]);
65 if x=y then exit(x);
66 for i:=maxm downto 0 do
67 begin
68 if c[i,x]<>c[i,y] then
69 begin
70 x:=c[i,x];
71 y:=c[i,y];
72 end;
73 end;
74 exit(c[0,x]);
75 end;
76
77 begin
78 readln(n,m);
79 for i:=1 to n do a[i]:=nil;
80 for i:=1 to n-1 do
81 begin
82 readln(j,k);
83 add(j,k);add(k,j);
84 end;
85 fillchar(d,sizeof(d),0);
86 fillchar(c,sizeof(c),0);
87 c[0,1]:=-1;
88 dfs(1);
89 for i:=1 to maxm do
90 for j:=1 to n do
91 c[i,j]:=c[i-1,c[i-1,j]];
92 for i:=1 to m do
93 begin
94 readln(j,k);
95 l:=getcom(j,k);
96 writeln(d[j]+d[k]-d[l]-d[l]);
97 end;
98 readln;
99 end.
100