Naive Dijkstra and heap optimization Dijkstra

Naive dijkstra: title

When facing the single-source shortest path problem, if all edges are positive weights, the Dijkstra algorithm can be used to solve the problem.
Idea: Maintain a collection of points with the shortest distance to the starting point that has not yet been determined. Each time a point with the shortest distance to the starting point is selected from the set, the shortest distance from the point to the starting point has been determined, delete from the set, and update All point distances related to this point (relaxation operation).
Time complexity: O(n^2), n is the number of points.

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 510;
int sides[N][N], dis[N];
bool cert[N]; // 判断点是否被确定

int dijkstra(int n)
{
    
    

    memset(dis, 0x3f, sizeof(dis));
    dis[1] = 0;
    
    for(int i = 1; i <= n ;i++)
    {
    
    
        int  t = -1;
        for(int j = 1; j <= n; j++) // 寻找距离最近的点
            if(!cert[j] && (t == -1 || dis[t] > dis[j])) t = j; 

        cert[t] = true;
        
        for (int i = 1; i <= n ;i++) //更新与该点有关的点的距离
            dis[i] = min(dis[i], dis[t] + sides[t][i]);
            
    }
    int ans = dis[n] == 0x3f3f3f3f? -1 : dis[n];
    return ans;
}

int main()
{
    
    
    memset(sides, 0x3f, sizeof(sides));

    int n, m;
    cin >> n >> m;

    int x, y, z;
    while(m--)
    {
    
    
        cin >> x >> y >> z;
        sides[x][y] = min(z, sides[x][y]); //在重边中选择最短一条
    }

    cout << dijkstra(n) << endl;
    return 0;

}

 

Heap optimized version of dijkstra: topic

In the naive algorithm, it can be found that all the points in the graph are scanned when looking for the point with the shortest distance. For this reason, the small root pile can be used to directly obtain the point with the shortest distance through the pile row.
Time complexity: O(mlogn), where n is the number of points, and m is the number of sides.

#include <iostream>
#include <cstring>
#include <utility>
#include <queue>


using namespace std;
const int N = 150010;

typedef pair<int, int> PII;
int idx, e[N], ne[N], w[N], h[N], dis[N];
bool cert[N];

void add(int a, int b, int c) // 不同于朴素dijkstra,在此使用邻接表
{
    
    
    e[idx] = b, w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}

int dijkstra(int n)
{
    
    
    memset(dis, 0x3f, sizeof(dis));
    priority_queue<PII, vector<PII>, greater<PII> > heap;
    
    heap.push({
    
    0, 1});

    while(heap.size())
    {
    
    
        int num = heap.top().second;
        int distance = heap.top().first;
        heap.pop();
        
        if(cert[num]) continue;

        for (int i = h[num]; i != -1; i = ne[i])
        {
    
    
            int t = e[i];
            if (dis[t] > distance + w[i])
            {
    
    
                dis[t] = distance + w[i];
                if(!cert[t]) heap.push({
    
    dis[t], t});
            }
        }
        
        cert[num] = true;
    }

    int ans = dis[n] == 0x3f3f3f3f? -1 : dis[n];
    return ans;
}

int main()
{
    
    
    memset(h, -1, sizeof(h));
    
    int n, m;
    cin >> n >> m;
    
    int x, y, z;
    while(m--)
    {
    
    
        cin >> x >> y >> z;
        add(x, y, z);
    }

    cout << dijkstra(n) << endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/PBomb/article/details/107640509