倍增LCA

HDU - 2586(倍增LCA):
多个询问求树上任意两点的距离。

import java.util.Arrays;
import java.util.Scanner;
public class Main
{   
    static int maxx=40005;
    static int maxn=16;
    static int head[]=new int[maxx];
    static int to[]=new int[maxx<<1];
    static int w[]=new int[maxx<<1];
    static int next[]=new int[maxx<<1];
    static int cnt;
    static void addEdge(int x,int y,int _w)
    {
        to[++cnt]=y;w[cnt]=_w;next[cnt]=head[x];head[x]=cnt;
        to[++cnt]=x;w[cnt]=_w;next[cnt]=head[y];head[y]=cnt;
    }
    static int deep[]=new int[maxx];
    static int fa[][]=new int[maxx][maxn];
    static int gw[][]=new int[maxx][maxn];
    static int N,n;
    static void init()
    {
        Arrays.fill(head, 0);
        cnt=0;
        N=(int) Math.floor(Math.log(n)/Math.log(2));
        deep[1]=0;
    }

    static void dfs(int root)
    {
        for(int i=1;i<=N;i++)
        {
            fa[root][i]=fa[fa[root][i-1]][i-1];
            gw[root][i]=gw[root][i-1]+gw[fa[root][i-1]][i-1];
        }
        for(int i=head[root];i>0;i=next[i])
        {
            int v=to[i];
            if(v==fa[root][0])
                continue;
            deep[v]=deep[root]+1;
            fa[v][0]=root;
            gw[v][0]=w[i];
            dfs(v);
        }
    }
    static int LCA(int a,int b)
    {
        if(deep[a]>deep[b])
        {
            int temp=a;
            a=b;
            b=temp;
        }
        int ans=0;
        for(int i=N;i>=0;i--)
        {
            if(deep[a]<deep[b]&&deep[a]<=deep[fa[b][i]])
            {
                ans+=gw[b][i];
                b=fa[b][i];
            }
        }
        for(int i=N;i>=0;i--) 
        {
            if(fa[a][i]!=fa[b][i])
            {
                ans+=gw[a][i];
                ans+=gw[b][i];
                a=fa[a][i];
                b=fa[b][i];
            }
        }
        if(a!=b)
        {
            ans+=gw[a][0];
            ans+=gw[b][0];
        }
        return ans;
    }
    public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        while(t-->0)
        {
            n=sc.nextInt();
            int m=sc.nextInt();
            init();
            for(int i=1;i<n;i++)
                addEdge(sc.nextInt(),sc.nextInt(),sc.nextInt());
            dfs(1);
            while(m-->0)
                System.out.println(LCA(sc.nextInt(),sc.nextInt()));     
        }

    }
}

猜你喜欢

转载自blog.csdn.net/coldfresh/article/details/80328065