Search code examples
algorithmdata-structuresgraphpriority-queuemin-heap

Is the visited array really needed in Dijkstra's Algorithm using Priority Queue?


vector<int> dijkstra(vector<vector<int>> &vec, int vertices, int edges, int source) 
{
    vector <pair<int,int>> adj[vertices];
    for (int i=0;i<edges;i++)
    {
        int u = vec[i][0];
        int v = vec[i][1];
        int w = vec[i][2];
        
        adj[u].push_back(make_pair(v,w));
        adj[v].push_back(make_pair(u,w));
    }
    
    vector<int> distance(vertices,INT_MAX);
    distance[source]= 0;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int> > > pq;
    pq.push(make_pair(0,source));
    
    while(!pq.empty())
    {
        int dis = pq.top().first;
        int node = pq.top().second;
        pq.pop();
        
        for (auto adjacentNode : adj[node])
        {
            int currNode = adjacentNode.first;
            int dfn = adjacentNode.second;
            
            if (dfn+dis < distance[currNode])
            {
                distance[currNode]= dfn+dis;
                pq.push(make_pair(distance[currNode], currNode));
            }
        }
    }

    return distance;
}

I was writing code for Dijkstra's Algorithm using priority queue but forgot to initialize the visited array to keep track of visited vertices. I submitted the code and all the test cases passed. Is the visited array really needed, or am I missing something?


Solution

  • This isn't really Dijkstra's algorithm, as Dijkstra's involves each node being added and removed from the priority queue at most once. This version will reinsert nodes in the queue when you have negative weight edges. It will also go into an infinite loop if you have negative weight cycles.

    Note that the wikipedia version uses a decrease key operation, it does not insert to the priority queue in the if statement.

    I don't know which version you're referring to that uses a visited array, but it's likely that visited array achieved the same purpose.

    This is closer to the Bellman-Ford algorithm, which can also be implemented with a queue (and it's usually faster in practice if you do it that way than if you do it as shown in most sources by iterating the edges |V| times). A priority queue achieves the same results, but it will be slower than a simple FIFO queue. It was probably fast enough for the online judge you submitted this to.

    Bottom line: what you have there isn't Dijkstra's algorithm. The visited array is likely necessary to make it Dijkstra's. You should edit your post to show that version as well so we can say for sure.