• LCA的RMQ求法


    参考博客

    仔细想一想:最近的公共祖先,其实,搜索时回朔,连通这两点,那深度最低肯定是最近的公共祖先啊。

    那这样就可以变成RMQ问题了。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int max_=41005;
    int ip,tot;
    struct Tree{//
       int to;
       int next;
       int v;
    };
    struct Tree a[max_*2];
    int first[max_];//第一次出现的位置
    int edge[max_];//边记录next
    int de[max_*2];//深度
    int id[max_*2];//遍历编号(包含回朔)
    int dis[max_];//到根的距离。
    int dp[max_*2][25];//st表,记录的是下标
    bool vis[max_];//标记数组
    void add_edge(int x,int y,int v)//建树
    {
        a[++ip].to=y;
        a[ip].v=v;
        a[ip].next=edge[x];
        edge[x]=ip;
    }
    void dfs(int x,int deep)//dfs遍历
    {
        if(vis[x]==0)
        {
            first[x]=tot;//记录第一次
            vis[x]=1;
        }
        de[tot]=deep,id[tot++]=x;
        for(int i=edge[x];i;i=a[i].next)
        {
            int go_to=a[i].to;
            if(vis[go_to])
                continue;
                int go_v=a[i].v;
                dis[go_to]=dis[x]+go_v;//跟新距离
                dfs(go_to,deep+1);
                id[tot]=x,de[tot++]=deep;
        }
    }
    int Min(int x,int y)//寻找最小深度
    {
        if(de[x]>de[y])
            return y;
        else
            return x;
    }
    void RMQ_ST(int len)
    {
        for(int i=0;i<len;i++)//初始化
            dp[i][0]=i;
        for(int j=1;(1<<j)<=len;j++)
            for(int i=0;i+(1<<j)-1<len;i++)
        {
            dp[i][j]=Min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
        }
    }
    int RMQ_question(int l,int r)
    {
        int k=0;
        while((1<<(k+1))<=r-l+1)k++;
        return Min(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    void itin()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        memset(edge,0,sizeof(edge));
        tot=0;
        ip=0;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            itin();
            int n,m;
            cin>>n>>m;
            for(int i=0;i<n-1;i++)
            {
                int x,y,v;
                cin>>x>>y>>v;
                add_edge(x,y,v);
                add_edge(y,x,v);
            }
            dfs(1,0);
            RMQ_ST(tot);
        for(int i=0;i<m;i++)
        {
            int u,v,k;
            cin>>u>>v;
            if(first[u]>first[v])//先出现的为左
            {
                k=RMQ_question(first[v],first[u]);
            }
            else
                k=RMQ_question(first[u],first[v]);
            int temp=dis[u]+dis[v]-(2*dis[id[k]]);
            cout<<temp<<endl;
                }
    }
        return 0;
    }
  • 相关阅读:
    DBUtils温习2
    DBUtils温习1
    C3P0连接池温习1
    JDBC复习2
    JDBC复习1
    Spring的AOP基于AspectJ的注解方式开发3
    Spring的AOP基于AspectJ的注解方式开发2
    Spring的AOP基于AspectJ的注解方式开发1
    高血压认知3
    pandas cookbook
  • 原文地址:https://www.cnblogs.com/linhaitai/p/9743196.html
Copyright © 2020-2023  润新知