Home > Blockchain >  Shortest path queries in a graph
Shortest path queries in a graph

Time:12-10

We are given a static graph of N nodes, where we have edges as given below:

 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.

We are given Q queries of type(u, v) and we need to find shortest path between nodes u and v.

Constraints :

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

Approach : Almost constant time - 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;
}

Will this approach work for every test case?

CodePudding user response:

  1. Add GCD claculation before LCM to provide path A => GCD(A,B) => B (done)

  2. When LCM checking fails, make factorization of values. If they are prime, move through "1" node. Otherwise check

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