• LCA(倍增)


    type arr=record v,nt:longint; end;
    const maxn=10008; lx=20;
    var lt:array[0..maxn] of longint;    
        eg:array[0..maxn*2] of arr;
        d:array[0..maxn] of longint;
        g:array[0..maxn,0..lx] of longint;
        n,i,x,y,a,b,sum:longint;
    procedure swap(var a,b:longint);
    var c:longint;
    begin
        c:=a; a:=b; b:=c;
    end;
    procedure add(x,y:longint);
    begin
        inc(sum); eg[sum].nt:=lt[x]; eg[sum].v:=y; lt[x]:=sum;
    end;
    procedure Tinit(x,fa:longint);
    var i:longint;
    begin
        g[x,0]:=fa; d[x]:=d[fa]+1;
        for i:=1 to lx do
            g[x,i]:=g[g[x,i-1],i-1];
        i:=lt[x];
        while i<>0 do
        begin
                    if eg[i].v<>fa then Tinit(eg[i].v,x);
            i:=eg[i].nt;
        end;
    end;
    function Tlca(x,y:longint):longint;
    var dep,i:longint;
    begin
        if d[x]<d[y] then swap(x,y);
        dep:=d[x]-d[y];
        for i:=0 to lx-1 do
            if dep and (1<<i) >0 then
                x:=g[x,i];
        if x=y then exit(x);
        for i:=lx-1 downto 0 do
            if g[x,i]<>g[y,i] then
            begin
                x:=g[x,i];
                y:=g[y,i];
            end;
        exit(g[x][0]);
    end;
    function Tdist(x,y:longint):longint;
    begin
        exit(d[x]+d[y]-d[Tlca(x,y)]*2);
    end;
    begin
        readln(n,a,b);
        sum:=0;
        while not eof do
        begin
            read(x);
            while not eoln do
            begin
                read(y);
                add(x,y);
                add(y,x);
            end;
            readln;
        end;
        Tinit(1,0);
        writeln(Tlca(a,b));
        writeln(Tdist(a,b));
    end.
  • 相关阅读:
    最小生成树+BFS J
    Noip 2016
    舒适的路线 (code[vs] 1001)
    拦截导弹 (加了神奇的位运算)
    逃出克隆岛 (codevs 2059)
    回家(洛谷 P1592)
    热浪
    城堡
    笔记 (一道正解思路巧妙的题)
    脱水缩合
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/4359747.html
Copyright © 2020-2023  润新知