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

Time:08-30

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?

CodePudding user response:

Since your algorithm keeps track of the (so far) shortest distance to a node, the if (dfn dis < distance[currNode]) statement will prevent the algorithm from revisiting nodes it had already visited, because the loop it made to revisit a node would add to the distance it already had for that revisited node, and so this condition is false (assuming positive weights).

So indeed, you don't need the visited array in this variant of Dijkstra's algorithm. See also how it is not there in the pseudo code that Wikipedia offers.

CodePudding user response:

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.

  • Related