C++ implements the shortest path algorithm (Dijkstra algorithm)

0Introduction

Dijkstra's algorithm is an algorithm that calculates the shortest path from a vertex to the rest of the vertex. It uses a greedy strategy and uses breadth first in its implementation. This algorithm is often learned and often forgotten, so write a blog to solve it completely.

1 Introduction to calculation steps

Dijkstra's calculation steps are not difficult, as follows

(1)设置一个集合表示已经标记过的节点,初始化为空
(2)使用一个数组d记录所有节点与源节点s的距离,初始化d[s] = 0,其余设置为INF
(3)循环n次
{
	在未标记的节点中,选出d值最小的节点x;
	将x加入标记过节点的集合;
	对于从x出发的所有边(x,y),更新d[y] = min(d[y],d[x]+w(x,y))
}

This principle is not difficult. I believe that readers can practice it a few times against the graph theory textbook. Let's implement it in conjunction with a specific topic on Leetcode.

2 Code combat

The following is the stem of Leetcode743. This question is a typical application of Dijkstra's algorithm. The question is not difficult. Use Dijkstra's algorithm to calculate the minimum distance from the source node to the remaining nodes. Finally, return to the maximum value of the node. If this graph is not a connected graph, return -1.

There are N network nodes, labeled 1 to N.
Given a list of times, it represents the transit time of the signal passing through the directed edge. times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time for a signal to pass from the source node to the target node.
Now, we send a signal from some node K. How long does it take for all nodes to receive the signal? If all nodes cannot receive the signal, return -1.
Input: times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
Output: 2
Insert picture description here

For the realization of Dijkstra's algorithm, the first problem to solve the problem is to establish a graph. For mapping, we use the adjacency list method, for each point, the connected point and the weight. When it is implemented, we abstract it as an edge and use a structure Edge, where u, v, and d are the source node, the destination node, and the weight in turn.

    struct Edge
    {
    
    
        int u,v,d;
        Edge(int from,int to,int dis)
            :      u(from),
                   v(to),
                   d(dis)
        {
    
    
        }
    };

Therefore, when building a graph, we use a vector<Edge> edgesrecord edge. When building a graph using the adjacency table, it is enough to record the subscript of the edge where the source node is located.
After the drawing is completed, use BFS to implement the calculation steps of the principle part. It is worth noting that there is a step in the calculation step. 在未标记的节点中,选出d值最小的节点x;For this step, we can use a priority queue to optimize it. u is the node to be marked, and d is the same The distance of the source node. Here is overloaded <to make it sort in ascending order in the priority queue.

    struct heapNode
    {
    
    
        int u,d;
        bool operator < (const heapNode& rhs) const
        {
    
    
            return d > rhs.d;
        }
    };

Let's take a look at all the code

class Solution {
    
    
public:
    struct Edge
    {
    
    
        int u,v,d;
        Edge(int from,int to,int dis)
            :      u(from),
                   v(to),
                   d(dis)
        {
    
    
        }
    };
    struct heapNode
    {
    
    
        int u,d;
        bool operator < (const heapNode& rhs) const
        {
    
    
            return d > rhs.d;
        }
    };
    int networkDelayTime(vector<vector<int>>& times, int N, int K) 
    {
    
    
        priority_queue<heapNode> que;
        vector<Edge> edges;
        vector<vector<int>> g(N,vector<int>());
        vector<int> d(N,INT_MAX);
        d[K-1] = 0;
        vector<int> visited(N,0);
        for(int i = 0; i < times.size();++i)//建图
        {
    
    
            edges.push_back(Edge{
    
    times[i][0]-1,times[i][1]-1,times[i][2]});
            g[times[i][0]-1].push_back(edges.size()-1);
        }
        que.push(heapNode{
    
    K-1,0});//先把源节点加进去
        while(!que.empty())
        {
    
    
            heapNode node = que.top();
            que.pop();
            if(visited[node.u])
                continue;
            visited[node.u] = 1;//标记
            for(int i = 0; i < g[node.u].size(); ++i)
            {
    
    
                Edge &edge = edges[g[node.u][i]];
                if(d[edge.v] > d[edge.u] + edge.d)//更新权值
                {
    
    
                    d[edge.v] = d[edge.u] + edge.d;
                    que.push(heapNode{
    
    edge.v,d[edge.v]});
                }
            }
        }
        int result = -1;
        for(int i = 0; i < d.size(); ++i)
        {
    
    
            if(d[i] > result)
                result = d[i];
        }
        return result == INT_MAX ? -1 : result;//判断是否是连通图
    }
};

Guess you like

Origin blog.csdn.net/MoonWisher_liang/article/details/108062789