前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法模板——LCA(最近公共祖先)

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

作者头像
HansBug
发布2018-04-10 16:40:39
1.1K0
发布2018-04-10 16:40:39
举报
文章被收录于专栏:HansBug's LabHansBug's Lab

实现的功能如下——在一个N个点的无环图中,共有N-1条边,M个访问中每次询问两个点的距离

原理——既然N个点,N-1条边,则说明这是一棵树,而且联通。所以以1为根节点DFS建树,然后通过求两点的LCA的方式,先求得最近公共祖先,然后再通过深度来求出两点距离

代码语言:javascript
复制
  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                                    
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-01-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档