0

I have implemented the Dijkstra's algorithm in C++ with the help of vectors. The problem description is available here. This passes all the test cases except one. The test case input causing the failure is available here

class CompareDistance{
    public:
        bool operator()(pair<int, int> node1, pair<int, int>node2){
            return node1.second > node2.second;
        };
};

void dijkstra(vector <list < pair<int, int> > > edgeList, int start, int nodes)
{
    priority_queue< pair<int, int>, vector< pair<int, int> >, CompareDistance > q;
    vector<int> distance(nodes + 1, -1);
    pair<int, int> currentNode;

    q.push(make_pair(start, 0));
    distance[start] = 0;

    while (!q.empty()){
        currentNode = q.top();
        q.pop();

        list< pair <int,int> >::iterator itr = edgeList[currentNode.first].begin();

        while(itr != edgeList[currentNode.first].end()){
            if(distance[itr->first] == -1 || ( ( distance[currentNode.first] +  itr->second ) < distance[itr->first]))
            {
                distance[itr->first] = distance[currentNode.first] + itr->second;
                q.push(make_pair(itr->first, distance[itr->first]));
            }
            itr++;
        }
    }

    for (int index = 1; index <= nodes; index++){
        if(index != start){
            cout << distance[index] << " ";
        }
    }
    cout<<endl;
}

int main()
{
    int query;
    //cout << "Number of queries : ";
    cin >> query;

    vector < vector < list < pair<int, int> > > > edgeList(query, vector < list < pair <int, int> > >(0));
    vector <int> nodes(query), edges(query), start(query);
    int index, v1, v2, v3, j;

    for (index = 0; index < query; index++){
        //cout << "Number of Nodes Edges : ";
        cin >> nodes[index] >> edges[index];

        edgeList[index].resize(nodes[index] + 1);
        for(j = 1; j < edges[index] +1; j++ ){
            cin >> v1 >> v2 >> v3;

            cout << "Pushing : " << j << endl;
            edgeList[index][v1].push_back( make_pair( v2, v3));
            edgeList[index][v2].push_back( make_pair( v1, v3));
        }

        cin >> start[index];
    }

    for(index = 0; index < query; index++){
        dijkstra(edgeList[index], start[index], nodes[index]);
    }
}

The above program hangs after printing the below output.

Pushing : 21702
Pushing : 21703

Graph of the last test case has 3121251 edges and my guess is that, vector fails to push all the elements.

Any suggestions on how to fix this are welcome.

Rohit Walavalkar
  • 790
  • 9
  • 28
  • I don't think that's the issue, but you can easily check it using vector.max_size() – FrankS101 Nov 30 '16 at 07:30
  • @FrankS101 Yes . vector supports more than 21703. But I am clueless about the behavior. I think since I am using nested vectors, there might be some restriction on the size – Rohit Walavalkar Nov 30 '16 at 07:35
  • The process never ends. Some times it results in a segmentation fault. But I haven't been able to deduce much from that either. – Rohit Walavalkar Nov 30 '16 at 07:48
  • 2
    If it is a bad subscript, valgrind will likely find it. That entire initial load should require about 400MB of RAM, then a crapton of CPU to do your calculation (the result of which, looked like [**this**](http://pastebin.com/5fP3iA5H) given enough time). I've not bothered to crunch it through VG, but I did yank the push call, as I quickly became bored watching it slowly count to over 3-million in my console. – WhozCraig Nov 30 '16 at 07:51
  • 1
    Look at the input graph, if the sum of the costs of a path overflows you can end up with a negative number, and we all know that Dijkstra's algorithm is not a big fan of such numbers ;) – FrankS101 Nov 30 '16 at 07:57
  • 1
    The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Nov 30 '16 at 07:59
  • Is there any reason why you store all test cases in a single vector instead of solving them as soon as you read them? – Holt Nov 30 '16 at 08:04
  • About `edgeList[index][v1]`: you are resizing `edgeList[index]` and indexing according to received input, so you'd better check that you're indexing within the size. – stefaanv Nov 30 '16 at 08:07
  • 1
    Ran it through valgrind, 12.4 million allocs and frees, 300MB total allocation footprint, and no out-of-ranges or leaks (I expected the latter would be ok, but the former is at least nice to know). Obviously the performance could be improved, but there you go. Good luck. – WhozCraig Nov 30 '16 at 08:20
  • Thanks. Will check on valgrind . Not an expert on valgrind, so I was hesitant. Thanks for the lead – Rohit Walavalkar Nov 30 '16 at 08:28

0 Answers0