-1

Lets say I have following graph: enter image description here

Now what I want is to get shortest path between every node in graph(or have -1 at that place in matrix if it is not possible to get from 1 node to other) , but that path need to have lenght less or same as K.

Now I tried using floyd-warshall algorithm replacing automatically path from 1 node to other if its length is less then K ,but that algorithm did not work on any test cases(not Time limit exceeded but Wrong answer).

This is how I did it:

// N is number of nodes, l is matrix, in l[x][y][0] I have shortest path from x to y and in l[x][y][1] is its lenght
for (int k = 0; k < N; k++) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            //if (this new path is shorter or there is not path yet) and current path lenght is not K(if it already reached max size) and both paths are not -1.
            if((l[i][j][0]>l[i][k][0]+l[k][j][0] || l[i][j][0]==-1) && l[i][j][1]<K && l[i][k][0]>-1 && l[k][j][0]>-1){
                //change max size
                l[i][j][0]=l[i][k][0]+l[k][j][0];
                //lenght of that path +=1
                l[i][j][1]+=1;
            }
        }
    }
}

for same number(like 3 and 3) I know it is wrong but later when outputing I puted that just print 0.

  • 3
    `not TLE but WA` -- Please do not use abbreviations or acronyms. State fully what these terms mean. – PaulMcKenzie Jan 30 '22 at 11:55
  • 2
    *but that algorithm did not work on any test cases* -- An algorithm meant to do the job *always* works. It is the code implementation of the algorithm that is faulty. So did you implement the algorithm correctly? – PaulMcKenzie Jan 30 '22 at 12:01
  • 1
    Are you sure this is valid c++ code?? What you seem to mean comments use `#`, which isn't valid for c++. Are you trying to convert python code actually? I think you have to [edit] and overhaule your question a lot, to get well appreciated here. – πάντα ῥεῖ Jan 30 '22 at 12:02
  • Thanks,@ πάντα ῥεῖ. No I was not trying to convert code but I was adding comments in question not in real code – User813291452 Jan 30 '22 at 12:03
  • 1
    @User813291452 post a [mcve] as required here, period! – πάντα ῥεῖ Jan 30 '22 at 12:04
  • @ PaulMcKenzie I wanted to say that floyd warshall is not working here so I need better algorithm. – User813291452 Jan 30 '22 at 12:04
  • [Wiki on shortest path algorithms](https://en.wikipedia.org/wiki/Shortest_path_problem#Directed_graphs_with_nonnegative_weights). – PaulMcKenzie Jan 30 '22 at 12:12

1 Answers1

1

l[i][j][1]+=1; it's wrong it should actually be l[i][j][1]=l[i][k][1]+l[k][j][1]; but this brakes your solution logic. So i recommend you do like this: count log(K) matrices: i-th matrix means length from j to k in no more than 2^i moves. Look at K in binary and when it-s 1 on i-th place you should recalc your ~current~ matrix with i-th matrix like this (not tested just for show the idea but seems that it would works. maybe should do --K for strict inequality):

#include <iostream>
#include <vector>

int my_log2(int index){
    int targetlevel = 0;
    while (index >>= 1) ++targetlevel;
    return targetlevel;
}

int main(){
    int N;
    int K;
    std::cin >> N >> K;
    std::vector < std::vector < std::vector < int > > > dist(my_log2(K), std::vector < std::vector < int > > (N, std::vector < int > (N)));
    for (int i = 0; i < N; ++i){
        for (int j = 0; j < N; ++j){
            // assume weights are positive and -1 if no edge between vertices
            // assume that dist[0][i][i] == 0
            std::cin >> dist[0][i][j];
        }
    }
    // can be easy rewriten to negative weights with same idea
    for (int i = 1; i < my_log2(K); ++i){
        for (int j = 0; j < N; ++j){
            for (int k = 0; k < N; ++k){
                dist[i][j][k] = -1;
                for (int l = 0; l < N; ++l){
                    if (dist[i - 1][j][l] > -1 && dist[i - 1][l][k] > -1 && (dist[i][j][k] == -1 || dist[i][j][k] > dist[i - 1][j][l] + dist[i - 1][l][k])){
                        dist[i][j][k] = dist[i - 1][j][l] + dist[i - 1][l][k];
                    }
                }
            }
        }
    }
    std::vector < std::vector < int > > old_current(N, std::vector < int > (N, -1));
    
    for (int i = 0; i < N; ++i){
        old_current[i][i] = 0;
    }
    for (int i = 0; i < my_log2(K); ++i){
        std::vector < std::vector < int > > new_current(N, std::vector < int > (N, -1));
        if (((K >> i) & 1) == 1){
            for (int j = 0; j < N; ++j){
                for (int k = 0; k < N; ++k){
                    for (int l = 0; l < N; ++l){
                        if (old_current[j][l] > -1 && dist[i][l][k] > -1 && (new_current[j][k] == -1 || new_current[j][k] > old_current[j][l] + dist[i][l][k])){
                            new_current[j][k] = old_current[j][l] + dist[i][l][k];
                        }
                        if (dist[i][j][l] > -1 && old_current[l][k] > -1 && (new_current[j][k] == -1 || new_current[j][k] > dist[i][j][l] + old_current[l][k])){
                            new_current[j][k] = dist[i][j][l] + old_current[l][k];
                        }
                    }
                }
            }
        }
        old_current = new_current;
    }
    // asnwer is in old_current
}