现在的位置: 首页 > 综合 > 正文

poj1330

2018年04月26日 ⁄ 综合 ⁄ 共 1408字 ⁄ 字号 评论关闭

【题意】

给定一棵树,两个节点的最早公共祖先

【输入】

第一行一个t表示数据组数

每组数据第一行一个n表示点数

接下来n-1行描述树,a b,表示b的父节点是a

之后一行a b表示询问a和b的最早公共祖先

【输出】

回答每组数据的询问

裸的lca问题,实际上由于只有一次询问,随便搞搞就行了,为了锻炼一下代码能力,写了个log级支持多组询问的程序,1A

program poj1330;
var
  who,a,b,tot,t,n,i,j,k:longint;
  height,next,point,root:array [0..10001] of longint;
  top:array [0..10001] of boolean;
  father:array [0..15,0..10001] of longint;

procedure swap (var a,b:longint);inline;
var
  i:longint;
begin
  i:=a;
  a:=b;
  b:=i;
end;

function lca (a,b:longint):longint;inline;
var
  i:longint;
begin
  if height[a]<height[b] then swap(a,b);
  while height[a]<>height[b] do
    a:=father[trunc(ln(height[a]-height[b])/ln(2)),a];
  if a=b then exit(a);
  i:=trunc(ln(height[a])/ln(2))+1;
  repeat
    if father[0,a]=father[0,b] then exit(father[0,a]);
    while father[i,a]=father[i,b] do dec(i);
    a:=father[i,a];
    b:=father[i,b];
  until false;
end;

procedure connect (u,v:longint);inline;
begin
  inc(tot);
  point[tot]:=v;
  next[tot]:=root[u];
  root[u]:=tot;
end;

procedure dfs (now,last,high:longint);
var
  i:longint;
begin
  height[now]:=high;
  father[0,now]:=last;
  i:=0;
  while 1 shl i<high do
    begin
      father[i+1,now]:=father[i,father[i,now]];
      inc(i);
    end;
  father[i,now]:=who;
  i:=root[now];
  while i<>0 do
    begin
      dfs(point[i],now,high+1);
      i:=next[i];
    end;
end;

begin
  read(t);
  while t>0 do
    begin
      dec(t);
      fillchar(root,sizeof(root),0);
      fillchar(top,sizeof(top),true);
      fillchar(father,sizeof(father),0);
      tot:=0;
      read(n);
      for i:=1 to n-1 do
        begin
          read(a,b);
          connect(a,b);
          top[b]:=false;
        end;
      for who:=1 to n do
        if top[who] then break;
      dfs(who,0,1);
      read(a,b);
      writeln(lca(a,b));
    end;
end.
【上篇】
【下篇】

抱歉!评论已关闭.