實現的功能如下——在乙個n個點的無環圖中,共有n-1條邊,m個訪問中每次詢問兩個點的距離
原理——既然n個點,n-1條邊,則說明這是一棵樹,而且聯通。所以以1為根節點dfs建樹,然後通過求兩點的lca的方式,先求得最近公共祖先,然後再通過深度來求出兩點距離
1type
2 point=^node;
3 node=record
4g:longint;
5next:point;
6end;7
const
8 maxn=100500
;9 maxm=trunc(ln(maxn)/ln(2))+1;10
var11
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;
15function
max(x,y:longint):longint;inline;
16begin
17if x>y then max:=x else max:=y;
18end;19
function
min(x,y:longint):longint;inline;
20begin
21if xthen min:=x else min:=y;
22end;23
procedure swap(var
x,y:longint);inline;
24var
z:longint;
25begin
26 z:=x;x:=y;y:=z;
27end;28
procedure
add(x,y:longint);inline;
29var
p:point;
30begin
31 new(p);p^.g:=y;
32 p^.next:=a[x];a[x]:=p;
33end;34
procedure
dfs(x:longint);inline;
35var
p:point;
36begin
37 p:=a[x];
38while p<>nil
do39
begin
40if c[0,p^.g]=0
then
41begin
42 c[0,p^.g]:=x;
43 d[p^.g]:=d[x]+1;44
dfs(p^.g);
45end
;46 p:=p^.next;
47end;48
end;
49function
getfat(x,y:longint):longint;inline;
50var
i,j,k:longint;
51begin
52 i:=0;53
while y>0
do54
begin
55if odd(y) then x:=c[i,x];
56 inc(i);y:=y div2;
57end;58
exit(x);
59end;60
function
getcom(x,y:longint):longint;inline;
61var
i:longint;
62begin
63if d[x]then
swap(x,y);
64 x:=getfat(x,d[x]-d[y]);
65if x=y then
exit(x);
66for i:=maxm downto0do
67begin
68if c[i,x]<>c[i,y] then
69begin
70 x:=c[i,x];
71 y:=c[i,y];
72end;73
end;
74 exit(c[0
,x]);
75end;76
77begin
78readln(n,m);
79for i:=1
to n do a[i]:=nil;80
for i:=1
to n-1
do81
begin
82readln(j,k);
83add(j,k);add(k,j);
84end
;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
90for j:=1
to n do
91 c[i,j]:=c[i-1,c[i-1
,j]];
92for i:=1
to m do
93begin
94readln(j,k);
95 l:=getcom(j,k);
96 writeln(d[j]+d[k]-d[l]-d[l]);
97end;98
readln;
99end
.100
模板 最近公共祖先(LCA)
題自洛谷 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b...
模板 lca 最近公共祖先
lca hljs cpp include include using namespace std const int maxn 500001 int n,m,gen,x,y struct edgeedge 2 maxn int deep maxn fa maxn 20 deep記錄每個點的深度,fa...
最近公共祖先 LCA 模板
lca即最近公共祖先,是指 在有根樹中,找出某兩個結點u和v最近的公共祖先。時間複雜度o nlogn m n 步驟 1.將樹看作乙個無向圖,從根節點開始深搜,得到乙個遍歷序列。2.在x y區間中利用rmq演算法找到深度最小返回其下標。可以上洛谷找模板題測試 include include inclu...