zoukankan      html  css  js  c++  java
  • POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    Description

    Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible!

    Input

    Lines 1..1+M: Same format as "Navigation Nightmare"

    Line 2+M: A single integer, K. 1 <= K <= 10,000

    Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.

    Output

    Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance.

    Sample Input

    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    3
    1 6
    1 4
    2 6

    Sample Output

    13
    3
    36

    Http

    POJ:https://vjudge.net/problem/POJ-1986
    UESTC:https://vjudge.net/problem/UESTC-256

    Source

    最近公共祖先LCA

    题目大意

    在一棵边带权的树上回答若干个两点之间距离的询问

    解决思路

    这题当然是用floyed解啦
    (以上纯属胡扯)
    在树上求两点之间的距离何必用Floyed呢?我们有LCA。

    那么如何用LCA解这道题呢?关于LCA倍增算法的基本思路请参照我的这篇文章

    但上文讲述的是边不带权的情况,本题中,我们要做一些改变。

    首先,为了方便起见,我们设根节点为1号点,那么Depth和Parent的定义都没有变,我们再加上一个Dist[u]表示u到1的距离(注意和Depth的区别,一个是深度,记录节点数,另一个是距离,记录边权和)

    那么两个点之间的距离就是Dist[u]+Dist[v]-2*Dist[LCA(u,v)]啦。
    简单解释一下,设u和v的最近公共祖先为p,u和v的距离首先可以是u到p的距离+v到p的距离,而u到p的距离又可以是Dist[u]-Dist[p],v也同理,所以两式相加就可以得到上面的式子了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    class Edge
    {
    public:
        int v,w;
    };
    
    const int maxN=210000;
    const int inf=2147483647;
    
    int n,m;
    vector<Edge> E[maxN];
    int Depth[maxN];
    int Dist[maxN];
    int Parent[maxN][23];
    bool vis[maxN];
    
    void LCA_init();
    void dfs(int u);
    int LCA(int a,int b);
    
    int main()
    {
        cin>>n>>m;
        for (int i=1;i<=m;i++)
        {
            int a,b,c;
            char ch;
            scanf("%d%d%d",&a,&b,&c);
            cin>>ch;
            E[a].push_back((Edge){b,c});
            E[b].push_back((Edge){a,c});
        }
        LCA_init();
        int Q;
        scanf("%d",&Q);
        for (int i=1;i<=Q;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            cout<<Dist[u]+Dist[v]-2*Dist[LCA(u,v)]<<endl;
        }
        return 0;
    }
    
    void LCA_init()
    {
        memset(Dist,0,sizeof(Dist));
        memset(Parent,0,sizeof(Parent));
        memset(Depth,0,sizeof(Depth));
        memset(vis,0,sizeof(vis));
        dfs(1);
        for (int j=1;j<=20;j++)
            for (int i=1;i<=n;i++)
                Parent[i][j]=Parent[Parent[i][j-1]][j-1];
        return;
    }
    
    void dfs(int u)
    {
        vis[u]=1;
        for (int i=0;i<E[u].size();i++)
        {
            int v=E[u][i].v;
            if (vis[v]==0)
            {
                Depth[v]=Depth[u]+1;
                Dist[v]=Dist[u]+E[u][i].w;
                Parent[v][0]=u;
                dfs(v);
            }
        }
        return;
    }
    
    int LCA(int a,int b)
    {
        if (Depth[a]<Depth[b])
            swap(a,b);
        for (int i=20;i>=0;i--)
            if ((Parent[a][i]!=0)&&(Depth[Parent[a][i]]>=Depth[b]))
                a=Parent[a][i];
        if (a==b)
            return a;
        for (int i=20;i>=0;i--)
            if ((Parent[a][i]!=0)&&(Parent[b][i]!=0)&&(Parent[a][i]!=Parent[b][i]))
            {
                a=Parent[a][i];
                b=Parent[b][i];
            }
        return Parent[a][0];
    }
    
  • 相关阅读:
    vue项目进行时,script标签中,methods事件中函数使用的async/await
    css阴影——box-shadow
    vue报错——Module not found: Error: Can't resolve 'less-loader sass' in ...
    vue组件如何引入外部.js/.css/.scss文件
    获得汉字的拼音或者拼音简写
    model转XML
    sql server 添加表注释、字段注释
    (转)SQL Server 监控统计阻塞脚本信息
    系统首页右下角弹框
    DropDownListExtend控件
  • 原文地址:https://www.cnblogs.com/SYCstudio/p/7150606.html
Copyright © 2011-2022 走看看