zoukankan      html  css  js  c++  java
  • CodeVS 2370-小机房的树

    原题

    题目描述 Description

    小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费c的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力.//题面有点恶心,但题还是挺不错的233

    输入描述 Input Description

    第一行一个n,接下来n-1行每一行有三个整数u,v,c.表示节点 u 爬到节点 v 需要花费 c 的精力.
    第n+1行有一个整数m表示有m次询问.接下来m行每一行有两个整数u,v表示两只虫子所在的节点.

    输出描述 Output Description

    一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离.

    样例输入 Sample Input

    3

    1 0 1

    2 0 1

    3

    1 0

    2 0

    1 2

    样例输出 Sample Output

    1

    1

    2

     

    数据范围及提示 Data Size & Hint

    1<=n<=50000, 1<=m<=75000, 0<=c<=1000

     

    题解

    LCA,最近公共祖先.

    用一个p数组储存节点i到根节点的距离.假设要求节点x与y之间的距离,则ans=p[x]+p[y]-2*p[lca(x,y)].

    代码:

     

    var p,f,ne,c,b,d:array[0..200010] of longint;
    var fa:array[0..100010,0..30] of longint;
    var n,m,i,j,k,z,x,y:longint;
    var v:array[0..100010] of boolean;
    procedure add(x,y,z:longint);
    begin
      inc(m);c[m]:=z;b[m]:=y;ne[m]:=f[x];f[x]:=m;
    end;
    function log(x:longint):longint;
    begin
      exit(trunc(ln(x)/ln(2)));
    end;
    procedure dfs(dep,num:longint);
    var j:longint;
    begin
      v[num]:=true;j:=f[num];d[num]:=dep;
      while j>0 do
      begin
        if not v[b[j]] then
        begin
          p[b[j]]:=p[num]+c[j];
          dfs(dep+1,b[j]);fa[b[j],0]:=num;
        end;
        j:=ne[j];
      end;
    end;
    function lca(x,y:longint):longint;
    var t,i,j,k:longint;
    begin
      if d[x]<d[y] then
      begin
        t:=x;x:=y;y:=t;
      end;
      k:=log(n);
      for i:=k downto 0 do if d[x]-1<<i>=d[y] then x:=fa[x,i];
      if x=y then exit(x);
      for i:=k downto 0 do
      begin
        if fa[x,i]<>fa[y,i] then
        begin
          x:=fa[x,i];y:=fa[y,i];
        end;
      end;
      exit(fa[x,0]);
    end;
    begin
      readln(n);
      fillchar(f,sizeof(f),255);
      for i:=1 to n-1 do
      begin
        readln(x,y,z);
        add(x,y,z);add(y,x,z);
      end;
      dfs(1,0);k:=log(n);
      for i:=1 to k do
      for j:=1 to n do fa[j,i]:=fa[fa[j,i-1],i-1];
      readln(m);
      for i:=1 to m do
      begin
        readln(x,y);
        writeln(p[x]+p[y]-p[lca(x,y)]*2);
      end;
    end.

     

     

    欢迎转载,若转载请注明出处.

  • 相关阅读:
    物联网操作系统HelloX开发者入门指南
    【 D3.js 高级系列 】 总结
    【 D3.js 高级系列 — 10.0 】 思维导图
    android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
    OpenGL 顶点缓存对象
    OpenGL顶点数组
    【 D3.js 高级系列 — 9.0 】 交互式提示框
    如何在 Linux 上录制你的终端操作
    程序员诗词大赛开始了_你看过吗?
    程序员与代码的搞笑日常
  • 原文地址:https://www.cnblogs.com/HAdolf-HQY/p/6389609.html
Copyright © 2011-2022 走看看