Detailed optimization algorithm Dijkstra heap

Heap algorithm optimization DIJ

DIJ time complexity of the algorithm is \ (O (n ^ 2) \) is, in some problems, the complexity of this obviously does not meet requirements. So we need to continue to explore ways DIJ optimization algorithm.

Heap principle of optimization

Heap optimization, by definition, is used to optimize the heap. We learn DIJ simple algorithm, the algorithm needs to understand DIJ from start to finish sweep over point and then find the smallest point of relaxation. The scanning operation is simple DIJ harm the culprit algorithm time complexity. So we use a small root heap, with priority queues to maintain the "minimum point." Thus greatly reducing the time complexity of the algorithm DIJ.

Heap optimized code implementation

easy to say, hard to do.

After we understand the above general idea, you can begin to write this code, but we found that the code has not dealt with a lot of details.

First, we need to priority queue shortest length push, but once into the team, will be a priority queue maintained automatically leave the original position, in other words, we can not point to it then it corresponds to the original, that is to say no number of points right to the point mapping approach to form.

We use the pair to solve this problem.

C ++ is a pair of carrying tuple. We can understand it as a structure of two elements. More exciting is the tuple has built Sort: a first keyword to the keyword, and then to the second sort key as the keyword. So, we keep distance with the first bit tuple, second bit number can be stored.

Then we found that the priority queue is actually large bare root heap, how do we make it into a small heap root of it?

There are two ways, the first one is to take the key opposite to the first number, and then take the time to take out the opposite number. The second is to redefine the priority queue:

priority_queue<int,vector<int>,greater<int> >q;

To solve these problems, we happily continue to write down, then we find that wrote relaxation, we obviously want the new value of relaxation is also pressed into the priority queue to go, this is the case, we found a problem: priority queue already exists in a number of same tuple (ie, the same second keyword), we have no way to delete it, there is no way to update it. So when we queues and running, there will be some bug.

How to do it? ?

When we began to enter the cycle of judgment: If there are repeated and top of the heap tuple, direct pop out, successfully maintaining the priority queue elements will not be repeated.

So we get a stack optimized code:

priority_queue<pair<int,int> >q;
void dijkstra(int start)
{
    memset(dist,0x3f,sizeof(dist));
    memset(v,0,sizeof(v));
    dist[start]=0;
    q.push(make_pair(0,start));
    while(!q.empty())
    {
        while(!q.empty() && (-q.top().first)>dist[q.top().second])
            q.pop();
        if(!q.empty())
            return;
        int x=q.top().second;
        q.pop();
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(dist[y]>dist[x]+val[i])
            {
                dist[y]=dist[x]+val[i];
                q.push(make_pair(-dist[y],y));
            }
        }
    }
}

Guess you like

Origin www.cnblogs.com/fusiwei/p/11390537.html