演算法模板 LCA(最近公共祖先)

2022-01-10 23:39:13 字數 3142 閱讀 6124

實現的功能如下——在乙個n個點的無環圖中,共有n-1條邊,m個訪問中每次詢問兩個點的距離

原理——既然n個點,n-1條邊,則說明這是一棵樹,而且聯通。所以以1為根節點dfs建樹,然後通過求兩點的lca的方式,先求得最近公共祖先,然後再通過深度來求出兩點距離

1

type

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...