图中的最短路径查询

Posted

技术标签:

【中文标题】图中的最短路径查询【英文标题】:Shortest path queries in a graph 【发布时间】:2022-01-14 03:37:54 【问题描述】:

我们得到一个由N 节点组成的静态,其中我们有,如下所示:

 1. node-1 to node-i (for all 2 <= i <= N) of weight N + 1.
 2. node-x to node-y (for all 2 <= x,y <= N) of weight 1, if and only if x divides y OR y divides x.

我们得到Q 类型(u, v) 的查询,我们需要找到节点uv. 之间的最短路径

约束:

T <= 10^5     // number of test cases
N <= 2 * 10^5 // number of nodes
Q <= 2 * 10^5 // number of queries
u,v <= N      

方法:几乎恒定的时间 - O(1)。

private int gcd(int x, int y) 
    if(x % y == 0) return y;
    return gcd(y, x % y);


private int lcm(int x, int y) 
    return (x * y) / gcd(x, y);


private int[] shortest_path(int N, int Q, int[][] queries) 
    int[] result = new int[Q];

    int[] smallestDivisor = new int[N + 1];
    for(int i = 2; i <= N; i++) 
        if(smallestDivisor[i] == 0) 
            int f = 1;
            while(i * f <= N) 
                if(smallestDivisor[i * f] == 0)
                    smallestDivisor[i*f] = i;
                f += 1;
            
           
    

    for(int i = 0; i < Q; i++) 
        int u = queries[i][0];
        int v = queries[i][1];
        int LCM = lcm(u, v);
        int GCD = gcd(u, v);

        int smallestDivisorOfU = smallestDivisor[u];
        int smallestDivisorOfV = smallestDivisor[v];

        if(u == v)
            result[i] = 0;       // if nodes are same 
        else if(u == 1 || v == 1)
            result[i] = N + 1;  // if any of the node is '1'
        else if(u % v == 0 || v % u == 0)
            result[i] = 1;      // if nodes are divisible
        else if(GCD != 1 || LCM <= N)
            result[i] = 2;    // if gcd != 1 || lcm exists thus we can go as: 'x' --> gcd(x, y)/lcm(x,y) --> 'y' : 2 distance
        else if(Math.min(smallestDivisorOfU * v, smallestDivisorOfV * u) <= N) 
            result[i] = 3;
        else
            result[i] = 2 * (N + 1); // we have to go via '1' node
    

    return result;

这种方法是否适用于每个测试用例?

【问题讨论】:

为什么选择 LCM 而不是 GCD?示例:节点 16,12 当 N @MBo,是的,我应该考虑这两种情况,对吗? GCD n 液晶模组。好像GCD == 1,比如说2个素数,那么我必须考虑LCM的情况,如果它存在,那么我们可以说最短距离是2,否则是2 * (N+1)。 是的,你完全正确 - 先 gcd,然后 lcm 如果 gcd==1 @MBo,将更新代码,您是否看到任何其他可能在 OP 的方法上失败的案例 我在回答中添加了提案 【参考方案1】:

    在 LCM 之前添加 GCD 计算以提供路径 A =&gt; GCD(A,B) =&gt; B(完成)

    当 LCM 检查失败时,对值进行因式分解。如果它们是素数,则通过"1" 节点。否则检查

   if (min(SmallestDivisorOfA * B , SmallestDivisorOfB * A) <= N) 
        result[i] = 3; 
Example: 7=>14=>2=>6

【讨论】:

以上是关于图中的最短路径查询的主要内容,如果未能解决你的问题,请参考以下文章

求图中任意两点之间最短路径有啥算法?

Floyd-Warshall求图中任意两点的最短路径

求c++ 程序 网络上两点间的最短路径

最短路径问题

干货最短路径问题

最短路径问题模型汇总