先上我原来的错误的代码

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. c# 设置winform程序为默认打开软件 在运行中获取参数

    1.右键→打开方式→选择默认程序→选择winform程序 2.修改Program.cs 判断注册的事件是否存在,如果不存在则运行实例,并把参数传入MainForm里,如果存在则把参数写到txt文件中, ...

  2. C++之STL一般总结

    重新复习一下STL 什么是STL? STL(模板和标准模板库),实现与类型无关的算法和数据类型,需要将实现中的类型参数化,允许用户根据它的需要制定不同的类型. 一.一般介绍 STL(Standard ...

  3. Javascript parseFloat内部解析规则

    这是由小习发的一个问题引起的讨论,结束后大家各自加深了多parseFloat的理解. 如下 16进制数0x10使用parseFloat转成数字,结果为0.潜意识期望的结果是16. 有人说脑残,16进制 ...

  4. Python 变量类型

    Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据 ...

  5. 一个PHP混淆后门的分析

    洒家的朋友的公司的某个站发现最近被上传了一个后门程序.为了取证我们抓取了HTTP请求流量,看到了一堆莫名其妙看似经过混淆的请求,响应也是看似base64的乱码.洒家用了2个小时静态分析了一遍,并写了利 ...

  6. IE自动跳转到标准模式

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

  7. Stanford机器学习笔记-9. 聚类(Clustering)

    9. Clustering Content 9. Clustering 9.1 Supervised Learning and Unsupervised Learning 9.2 K-means al ...

  8. AC日记——组合数问题 落谷 P2822 noip2016day2T1

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  9. Flex(flash)检测摄像头的3种状态(是否被占用,没安装摄像头,正常)

    在视频程序的编写过程中,我们经常要使用摄像头,在使用摄像头前有必要对摄像头的现有状态做个检测: 1.被占用 2.没安装摄像头 3.正常 camera=Camera.getCamera();       ...

  10. java 24 - 6 GUI之 创建只能输入数字的文本框

    需求: 创建一个含有标签和文本框的窗体,其中文本框只能输入数字 步骤:(大致上) 创建窗体对象 创建标签对象 创建文本框对象 把组件添加到窗体中 设置标签的监听事件,对键盘按下的数据进行监听 设置窗体 ...