[Algorithm learning] Dijkstra algorithm for priority queue optimization to find the shortest path

dijkstra can be used to find the shortest path from a single vertex to other vertices

The core idea is DP, use the shortest path that has been found to update the shortest path to other points

The time complexity is excellent but not suitable for graphs with negative weight edges.

 

Specific method: use dis to store the current distance from the starting point to each point, initialized to inf, and the distance to yourself initialized to 0

    Every time the point closest to the starting point is taken, use this point to update the distance from the starting point to other points, and then mark to avoid repeated operations

    The naive approach is O (n ^ 2), but we can use the feature that the minimum distance is taken out every time to optimize it with the priority queue

 

Code:

const  int maxn = 1e4 + 5 ;
 int n, m, s;
 struct edge {
     int to, w; 
}; 

struct node {
     int w, now;
     bool  operator <( const node a) const {
         return w> aw; 
    } 
} ; 

int a, b, c; 
vector <edge> mp [maxn]; // vector save edge 
int dis [maxn];                   
priority_queue <node> q; // priority queue processes each vertex 
int f [maxn];     //Mark whether the current vertex has been updated to other points 

int main () { 
    cin >> n >> m >> s; 

    while (m-- ) { 
        scanf ( " % d% d% d " , & a, & b, & c); 
        mp [a] .push_back (edge ​​{b, c}); 
    } 
    // Read the edge 
    
    for ( int i = 1 ; i <= n; i ++ ) 
        dis [i] = 0x3f3f3f3f ; 
    dis [s] = 0 ;
     // Initialize dis array 

    q.push (node ​​{ 0 , s});
     while (! Q.empty ()) { 
        node x= q.top();
        q.pop();
        int u = x.now;
        if(f[u]) continue;
        f[u] = 1;
        for(int i = 0; i < mp[u].size(); i++){
            if(dis[mp[u][i].to] > dis[u] + mp[u][i].w){
                dis[mp[u][i].to] = dis[u] + mp[u][i].w;
                q.push(node{dis[mp[u][i].to], mp[u][i].to});
            }
        } //dijkstra核心代码
    }
    //优先队列处理

    for(int i = 1; i <= n; i++)
        cout<<dis[i]<<" ";
    return 0;
}

The core of dijkstra is

if(dis[mp[u][i].to] > dis[u] + mp[u][i].w){
                dis[mp[u][i].to] = dis[u] + mp[u][i].w;

If you can shorten the distance, update the distance and enqueue the point (because it is already the closest point to the starting point, the updated distance will also be the shortest distance, other points cannot update it to a shorter distance)

Therefore, after each update, the enqueue point is already the shortest distance from the source point, so each point only needs to enqueue once.

Thereby O (mlogn) complexity

 

Guess you like

Origin www.cnblogs.com/leafsblogowo/p/12691922.html