Implementation of dijkstra algorithm (743, 787) for priority queue of shortest path problem in leetcode graph

743 network delay time

Topic Description: there are N network nodes, marked as 1 to N. Given a list of times, it indicates the time of 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 when a signal passes from the source node to the target node.
Now, we send a signal to the current node K. How long does it take for all nodes to receive signals? If you cannot signal all nodes, return - 1.
Note: the range of N is between [1, 100].
The range of K is between [1, N].
The length of times is between [1, 6000].
All edges times[i] = (u, v, w) have 1 < = u, V < = n and 0 < = w < = 100.
Idea: the problem can be transformed into solving the maximum value of the shortest path from a given vertex to any vertex in a weighted digraph. Because all the weight values are positive, dijkstra algorithm can be considered. See the comments in the code for specific ideas.

// dijkstra algorithm of priority queue (dijkstra can be optimized by priority queue)
class node {
// Node node stores the id of each vertex in the graph and the distance from the vertex to the starting vertex
// This distance is not necessarily the final minimum distance
    public:
        int id;
        int dis;
        friend bool operator < (const node x, const node y) {  // The sorting rule of overloaded priority queue, and the first out queue with small dis 
            return x.dis > y.dis;
        }
};
class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int N, int K) {
        int ans = 0;
        int cnt = 0;
        vector<vector<node>> edges(N + 1); // Structural map
        for(int i = 0; i < times.size(); i++) { //Store the adjacent vertex information of each point
            edges[times[i][0]].push_back(node{times[i][1], times[i][2]});
        }
        vector<int> vis(N + 1, -1); // Store the shortest distance from each point to the starting point. The distance keeps updating and getting smaller
        priority_queue<node> Q; // dijkstra with priority queue
        Q.push(node{K, 0}); // Press in starting point
        vis[K] = 0;
        while(!Q.empty()) {
            node u = Q.top();
            Q.pop();
            if(u.dis > vis[u.id]) // Pruning according to the stack rule of priority queue, the first out stack with a small dis value is always updated to the minimum distance in the VIS array. Once u.dis > vis [u.id], it means that the second out stack of the u.id vertex also has a larger dis value. At this time, cnt does not accumulate and directly pop the next node.
                continue;
            cnt++;
            //cout<< cnt<<endl;
            ans = max(ans, u.dis); // Keep updating maximum answers
            for(int i = 0; i < edges[u.id].size(); i++) {
                int v = edges[u.id][i].id;
                if(vis[v] == -1 || vis[v] > edges[u.id][i].dis + u.dis) {
                    vis[v] = edges[u.id][i].dis + u.dis; // Update vis array
                    Q.push(node{v, vis[v]});
                }
            }
        }
        if(cnt < N)
            return -1;
        return ans;
    }
};

The cheapest flight in transit at 787 K

Title Description: there are n cities connected by m flights. Each flight starts from city u and arrives at v at price w. Now given all the cities and flights, as well as the departure city src and destination dst, your task is to find the cheapest price from src to dst through the most k stations. If there is no such route, output - 1.
Note: n range is [1, 100], city label from 0 to n - 1
The range of the number of flights is [0, n * (n - 1) / 2]
The format of each flight (src, dst, price)
The price range for each flight is [1, 10000]
The range of k is [0, n - 1]
The flight is not repeated and there is no loop
Idea 1: dijkstra is implemented by priority queue. The basic idea is the same as the above. But a condition has been added: transfer through K station at most. That is, the shortest distance and the number of transfer stations should be considered at the same time. In all the paths from the starting point to the arriving point, every possible number of transfer stations (0,1 ·· k-1,k) less than the number k has corresponding shortest distances, which are not the same. We need to find the minimum value of the shortest distance from the starting point to the transfer station which is less than or equal to K. See the code for specific ideas.
Train of thought 2: dynamic planning. To be supplemented.

class node {
    public:
        int id;
        int dis;
        int cnt; // transfer
        friend bool operator < (const node a, const node b) {
            return a.dis > b. dis; 
        }
};
class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<vector<node>> edges(n);
        for(int i = 0; i < flights.size(); i++) {
            edges[flights[i][0]].push_back(node{flights[i][1], flights[i][2], -1});
        }
        vector<vector<int>> vis(K + 2, vector<int>(n, -1));
        priority_queue<node> Q;
        Q.push(node{src, 0, 0});
        vis[0][src] = 0; // The first dimension of a two-dimensional matrix is the number of transitions, and the second dimension is the vertex id
        while(!Q.empty()) {
            node q = Q.top();
            Q.pop();
            cout<<q.id<<" "<<q.dis<<" "<<q.cnt<<endl;
            if(q.dis > vis[q.cnt][q.id]) // If it is greater than, it means that the shortest node is out of the stack
                continue;
            if(q.id == dst && q.cnt <= K + 1)
                return q.dis;
            if(q.cnt == K+1) // Prune
                continue;
            for(int i = 0; i < edges[q.id].size(); i++) {
                int v = edges[q.id][i].id;
                if(vis[q.cnt + 1][v] == -1 || vis[q.cnt + 1][v] > q.dis + edges[q.id][i].dis) {
                    vis[q.cnt + 1][v] = q.dis + edges[q.id][i].dis;
                    Q.push(node{v, q.dis + edges[q.id][i].dis, q.cnt + 1});
                }
            }
        }
        return -1;
    }
};

1334 the city with the least neighbors within the threshold distance

Title Description: there are n cities, numbered from 0 to n-1. Give you an edge array edge, where edge [i] = [fromi, toi, weighti] represents the two-way weighted edge between the two cities of fromi and toi, and the distance threshold is an integer distance threshold.
Returns the city with the minimum number of other cities and the maximum distance of distance threshold through some paths. If there are more than one such city, the city with the largest number is returned. Note that the distance of the path connecting cities i and j is equal to the sum of the weights along all sides of the path.
Note: 2 < = n < = 100
1 <= edges.length <= n * (n - 1) / 2
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti, distanceThreshold <= 10^4
All (fromi, toi) are different.
Idea: dijkstra is implemented by priority queue. The idea is the same as problem 743, but to traverse each vertex, each vertex is regarded as the starting vertex, and the number of neighbors whose distance is less than the threshold distance is counted. See code Notes for details of implementation.

// The implementation of dijkstra with priority queue of question 743
class node {
    public:
        int id;
        int dis;
        friend bool operator < (const node x, const node y) { // Customize the sorting method in the priority queue
            return x.dis > y.dis; // The priority queue is from large to small by default. After overloading, it becomes from small to large.
        }
};
class Solution {
public:
    // Start is the start node. If the minimum value in the priority queue exceeds the distance threshold, you can return directly
    // Returns how many cities are less than or equal to distanceThreshold
    int dijkstra(vector<int> &dis, vector<vector<node>> &edges, int start, int distanceThreshold) {
        priority_queue<node> Q;
        Q.push(node{start, 0});
        dis[start] = 0;
        int cnt = 0;
        while(!Q.empty()) {
            node u = Q.top();
            Q.pop();
            // Prune
            if(u.dis > distanceThreshold) // Since it is the priority queue, once the distance out of the queue starts to be greater than the threshold, then the distance out of the queue must also be greater than the threshold
                return cnt;
            if(u.dis > dis[u.id]) // The vertex distance will be updated because it is a priority queue, and the updated distance must be later than the updated distance. The distance corresponding to the first time the same vertex is out of the queue is the shortest distance. Only then can cnt++
                continue;
            cnt += 1;
            for(int i = 0; i < edges[u.id].size(); i++) {
                int v = edges[u.id][i].id;
                if(dis[v] == -1 || dis[v] > edges[u.id][i].dis + u.dis) {
                    dis[v] = edges[u.id][i].dis + u.dis;
                    Q.push(node{v, dis[v]});
                }
            }
        }
        return cnt;
    }

    int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
        vector<vector<node>> e(n);
        for(int i = 0; i < edges.size(); i++) {
            e[edges[i][0]].push_back(node{edges[i][1], edges[i][2]});
            e[edges[i][1]].push_back(node{edges[i][0], edges[i][2]});
        }
        int ans = 0, cnt_city = n;
        for(int i=0; i<n; i++) {
            vector<int> dis(n, -1);
            int cnt = dijkstra(dis, e, i, distanceThreshold);
            // cout << i << " " << cnt << endl;
            if(cnt <= cnt_city) {
                cnt_city = cnt;
                ans = i;
            }
        }
        return ans;
    }
};
Published 17 original articles, won praise 0, visited 246
Private letter follow

Tags: less network

Posted on Sun, 02 Feb 2020 03:43:31 -0500 by little_tris