先上我原来的错误的代码

type
node=^link;
link=record
num:int64;
next:node;
end; var
fa:array[..,..] of int64;
dep:array[..] of int64;
nd:array[..] of node;
b:array[..] of boolean;
dl:array[..] of int64;
n,m,maxdep,ans,t1,t2:int64;
i:longint; procedure maketree;
var
t1,t2,head,tail:int64;
i,j:longint;
p:node;
begin for i:= to n do
b[i]:=false; for i:= to n- do
begin
read(t1,t2); new(p);
p^.num:=t2;p^.next:=nd[t1];nd[t1]:=p;
new(p);
p^.num:=t1;p^.next:=nd[t2];nd[t2]:=p;
end; new(p);
head:=;tail:=;dl[head]:=;b[]:=true;
while head<=tail do
begin
p:=nd[dl[head]]; while p<>nil do
begin
if b[p^.num]=false then
begin
inc(tail);
dl[tail]:=p^.num;
fa[p^.num,]:=dl[head];
dep[p^.num]:=dep[dl[head]]+;
b[p^.num]:=true;
if dep[p^.num]>maxdep then maxdep:=dep[p^.num];
end;
p:=p^.next;
end; inc(head);
end; for j:= to trunc(ln(maxdep)/ln())+ do
for i:= to n do
if dep[i]>=<<j then
fa[i,j]:=fa[fa[i,j-],j-];
end; procedure lca(a,b:longint);
var
i,t:longint;
begin
if dep[a]>dep[b] then
begin
t:=a;
a:=b;
b:=t;
end; if dep[a]<>dep[b] then
for i:=trunc(ln(dep[b]-dep[a])/ln()) downto do
if dep[b]-<<i>=dep[a] then
begin
b:=fa[b,i];
ans:=ans+<<i;
end; if a<>b then
for i:=trunc(ln(dep[a])/ln()) downto do
if fa[a,i]<>fa[b,i] then
begin
a:=fa[a,i];
b:=fa[b,i];
ans:=ans+<<(i+);
end; if a<>b then inc(ans,);
end; begin readln(n); if n= then
begin
writeln();
halt;
end; maketree; readln(m); read(t1);
for i:= to m do
begin
read(t2); lca(t1,t2);
t1:=t2;
end; writeln(ans); end.

这个写法WA了一个点,答案比标准答案大。

最后发现可能是ln出现了误差,导致结果偏小,使两点无法移到同层。在后面的移动中无论怎样都无法移到同点,使答案比原来大二

改正后的模板

type
node=^link;
link=record
num:int64;
next:node;
end; var
fa:array[..,..] of int64;
dep:array[..] of int64;
nd:array[..] of node;
b:array[..] of boolean;
dl:array[..] of int64;
n,m,maxdep,ans,t1,t2:int64;
i:longint; procedure maketree;
var
t1,t2,head,tail:int64;
i,j:longint;
p:node;
begin for i:= to n do
b[i]:=false; for i:= to n- do
begin
read(t1,t2); new(p);
p^.num:=t2;p^.next:=nd[t1];nd[t1]:=p;
new(p);
p^.num:=t1;p^.next:=nd[t2];nd[t2]:=p;
end; new(p);
head:=;tail:=;dl[head]:=;b[]:=true;
while head<=tail do
begin
p:=nd[dl[head]]; while p<>nil do
begin
if b[p^.num]=false then
begin
inc(tail);
dl[tail]:=p^.num;
fa[p^.num,]:=dl[head];
dep[p^.num]:=dep[dl[head]]+;
b[p^.num]:=true;
if dep[p^.num]>maxdep then maxdep:=dep[p^.num];
end;
p:=p^.next;
end; inc(head);
end; for j:= to trunc(ln(maxdep)/ln())+ do
for i:= to n do
if dep[i]>=<<j then
fa[i,j]:=fa[fa[i,j-],j-];
end; procedure lca(a,b:longint);
var
i,t:longint;
begin
if dep[a]>dep[b] then
begin
t:=a;
a:=b;
b:=t;
end; if dep[a]<>dep[b] then
for i:=trunc(ln(dep[b]-dep[a])/ln())+ downto do
if dep[b]-<<i>=dep[a] then
begin
b:=fa[b,i];
ans:=ans+<<i;
end; if a<>b then
for i:=trunc(ln(dep[a])/ln())+ downto do
if fa[a,i]<>fa[b,i] then
begin
a:=fa[a,i];
b:=fa[b,i];
ans:=ans+<<(i+);
end; if a<>b then inc(ans,);
end; begin readln(n); if n= then
begin
writeln();
halt;
end; maketree; readln(m); read(t1);
for i:= to m do
begin
read(t2); lca(t1,t2);
t1:=t2;
end; writeln(ans); end.

LCA倍增算法的错误与模板的更多相关文章

  1. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

  2. 最近公共祖先 LCA 倍增算法

          树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...

  3. POJ 1330 Nearest Common Ancestors (LCA,倍增算法,在线算法)

    /* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 F ...

  4. LCA 倍增算法模板

    . #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm&g ...

  5. 算法笔记--lca倍增算法

    算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...

  6. LCA(最近公共祖先)之倍增算法

    概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...

  7. LCA(倍增在线算法) codevs 2370 小机房的树

    codevs 2370 小机房的树 时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...

  8. Lca 之倍增算法

    引入: 比如说要找树上任意两个点的路上的最大值.如果是一般的做法 会 接近o(n)的搜,从一个点搜到另一个点,但是如果询问多了复杂度就很高了. 然后我们会预处理.预处理是o(n²)的,询问是o(1)的 ...

  9. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

随机推荐

  1. SQL SERVER同步环境新增发布对象时不能生成(sp_MS+表名)同步存储过程

    在配置了同步的用户环境(订阅端:请求订阅) 在发布端: 1.企业管理器SSMS—复制—本地发布—发布属性—项目(选中发布对象) 2.在企业管理里—查看快照代理状态(启动) 在订阅服务器: USE [D ...

  2. python 笔记(一) —— 不要误用 ++i、--i

    ilocker:关注 Android 安全(新手) QQ: 2597294287 在 python 中也可以写 ++i,但含义完全不同于 c/c++.python 的 ++i 并不是将 i 自增 1, ...

  3. Java与模式读书笔记

    >设计目标:可扩展性,灵活性,可插入性. >设计原则 ● Open Closed Principle 开闭原则 对扩展开放,对修改关闭. 对面向对象的语言来说,不可以更改的是系统的抽象层, ...

  4. python笔记-调用eval函数出现invalid syntax错误

    本来是想打算使用eval函数对变量进行赋值的,没想到出现了invalid syntax错误.源代码如下 In [2]: eval('a = 1') File "<string>& ...

  5. 分页查询的两种方法(双top 双order 和 row_number() over ())

    --跳过10条取2条 也叫分页select top 2 * from studentwhere studentno not in (select top 2 studentno from studen ...

  6. java 26 - 8 网络编程之 TCP协议的练习

    TCP练习: 1.客户端键盘录入,服务器输出文本文件 客户端代码: public class ClientDemo { public static void main(String[] args) t ...

  7. 获取assemblies信息in .net core

    using System; using System.Linq; using System.Reflection; using System.Runtime.Loader; using Microso ...

  8. ESXi 5.5 解决 cannot edit the settings of virtual machines of version 10

    ESXi 5.5 是VMWare提供的免费虚拟服务器软件, 因为其优秀的性能, 对CPU, 内存和虚拟机数量都解除了限制, 成为很多个人或者小型公司的首选虚拟化工具. 在日常管理时常碰到的一个问题是, ...

  9. http://www.cnblogs.com/figure9/p/developer-reading-list.html

    http://www.cnblogs.com/figure9/p/developer-reading-list.html

  10. Java设计模式之-----策略模式

    首先,我们来看下策略模式的概念.一般的解释如下:     策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(原文:The St ...