hdu 2586 How far away ?倍增LCA

Posted lemonsbiscuit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 2586 How far away ?倍增LCA相关的知识,希望对你有一定的参考价值。

hdu 2586 How far away ?倍增LCA

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=2586

思路:

  • 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组
  • 因为
  • \(2^{16} > 40000\)
  • 所以所以表示祖先的数组dp[][]第二维取到16即可
  • 就这道题来说,与比较tarjan比较,稍快一点

    代码:

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    using namespace std;
    const int maxn = 40005;
    const int maxm = 80005;
    struct node {
    int to,next,w;
    }edges[maxm];
    int head[maxn],cnt,dp[maxn][17],dep[maxn],dist[maxn];
    inline void addedge(int u, int v, int w) {
    edges[cnt].to=v;
    edges[cnt].w=w;
    edges[cnt].next=head[u];
    head[u]=cnt++;
    }
    void dfs(int s, int x) {
    dp[s][0]=x;
    dep[s]=dep[x]+1;
    int t;
    for(int i=1;(1<<i)<=dep[s];++i)
        dp[s][i]=dp[dp[s][i-1]][i-1];
    for(int i=head[s];i!=-1;i=edges[i].next) {
        t=edges[i].to;
        if(t==x) continue;
        dist[t]=dist[s]+edges[i].w;
        dfs(t,s);
    }
    }
    inline int lca(int u, int v) {
    if(dep[v]>dep[u]) swap(u,v);
    for(int i=16;i>=0;--i) {
        if((1<<i)<=(dep[u]-dep[v])) {
            u=dp[u][i];
        }
    }
    if(u==v) return u;
    for(int i=16;i>=0;--i) {
        if((1<<i)<=dep[u]&&(dp[v][i]!=dp[u][i])) {
            u=dp[u][i];
            v=dp[v][i];
        }
    }
    return dp[u][0];
    }
    inline int slove(int u ,int v) {
    int z=lca(u,v);
    return dist[u]-2*dist[z]+dist[v];
    }
    inline void init() {
    cnt=0;
    memset(head,-1,sizeof(head));
    }
    int main() {
    int t,n,m,u,v,w;
    scanf("%d",&t);
    while(t--) {
        scanf("%d %d",&n,&m);
        init();
        for(int i=1;i<n;++i) {
            scanf("%d %d %d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        dep[1]=0;//保持dfs的统一,实际dep[1]=1
        dist[1]=0;
        dfs(1,1);
        for(int i=1;i<=m;++i) {
            scanf("%d %d",&u,&v);
            printf("%d\n",slove(u,v));
        }
    }
    return 0;
    }

以上是关于hdu 2586 How far away ?倍增LCA的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 2586 How far away ?

HDU - 2586 How far away ?(暴力 | LCA)

hdu 2586 How far away ?

HDU 2586 How far away ?

HDU2586---How far away ?(lca算法)

HDU-2586 How far away?