算法模板——LCA(最近公共祖先)
时间:2022-05-07
本文章向大家介绍算法模板——LCA(最近公共祖先),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实现的功能如下——在一个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
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CentOS 6.5中利用yum搭建LNMP环境的步骤详解
- Linux下Kafka分布式集群安装教程
- Centos下升级Python及Mongodb驱动安装问题
- centOS6中使用crontab定时运行执行jar程序的脚本
- 基于cobbler 实现自动安装linux系统
- Polysh命令实现多日志查询的方法示例
- linux中启动tomcat后浏览器无法访问的解决方法
- Linux查看系统配置常用命令详解
- LNMP下提示File not found问题的解决方法
- Linux 配置SSH免密登录 “ssh-keygen”的基本用法
- 详解Ubuntu 16.04 pycharm设置桌面快捷启动方式
- Linux 7.4上安装配置Oracle 11.2.0.4图文教程
- linux磁盘管理软RAID的实现原理分析和方法分享
- Centos7下Samba服务器配置(实战)
- Linux系统中创建SSH服务器别名的两种方法