2045. Second short time to destination

Posted by habs20 on Thu, 27 Jan 2022 23:53:54 +0100

Difficulty: difficulty

catalogue

1, Problem description

2, Problem solving thought

3, Problem solving

1. Judge extreme situations

2. Code implementation

4, Summary

1, Problem description

The problem description above LeetCode is directly used here.

Cities are represented by a two-way connected graph, in which there are n nodes, numbered from 1 to n (including 1 and N). The edges in the graph are represented by a two-dimensional integer array edges, where each edge [i] = [ui, vi] represents a two-way connected edge between node ui and node VI. Each group of node pairs is connected by at most one edge, and the vertex has no edge connected to itself. The time to cross either side is time minutes.

Each node has a traffic light, which changes once every change minute, from green to red, and then from red to green, in a cycle. All signal lights change at the same time. You can enter a node at any time, but you can only leave when the node signal is green. If the signal light is green, you can't wait at the node and must leave.

The second smallest value , is the smallest of all values where , is strictly greater than , the minimum value.

  • For example, the second smallest value in [2, 3, 4] is 3, while the second smallest value in [2, 2, 4] is 4. Give you n, edges, time and change, and return the second short time from node 1 to node n.

be careful:

  • You can pass through any vertex any time, including 1 and n.
  • You can assume that when you leave, all the lights just turn green.

Examples are given below:

Tips:

  • 2 <= n <= 104
  • n - 1 <= edges.length <= min(2 * 104, n * (n - 1) / 2)
  • edges[i].length == 2
  • 1 <= ui, vi <= n
  • ui != vi
  • Without duplicate edges
  • Each node can arrive directly or indirectly from other nodes
  • 1 <= time, change <= 103

 

2, Problem solving thought

The first thing I think about is DFS and BFS. But this problem is not to find the shortest path of the graph, but the time to find the sub shortest path of the graph. And before 1345. Jumping game IV leetcode There are similarities and differences. That question is to find the shortest path to the last node, and this question is to find the time of the second shortest path.

It should be noted that the title says: you can pass through any vertex any time, including 1 and n. It means that you can go back through the source point and then go to the target node. In the following figure, when the node is 2, it needs to pass through the source point once. This is the second short path.

 

We can still use BFS. Here, we need to maintain a table of the shortest path and sub shortest path from the source point to other nodes.

Preparation before using BFS:

  1. Initialize vector < vector < int > > path(n+1, vector < int > (2, INT_MAX)) (path[i][0] stores the shortest path length from the source point to node i, and path[i][1] stores the second shortest path length from the source point to node i). Set the distance of path[1][0] to 0.
  2. Define queue {queue < pair < int, int > > Q (queue {Q {i, j} is used to store the distance {j} from the source point to node {i}). Join the team {1,0} BFS from the source point.

Operations required by BFS:

  1. Judge whether the path from the source point to the current node is strictly less than the minimum path, and maintain the shortest path path[i,0]. (i is the node of the current BFS)
  2. Judge whether the path from the source point to the current node is strictly greater than the minimum path and strictly less than the secondary short path, and maintain the secondary short path[i][1]. (I is the node of the current BFS)

Finally, it is necessary to convert the sub short path into sub short time. Since the light is green at the beginning, it is green again every , 2*change ,; Only when the time of the current node is: ans% (2*change) > = change, the waiting time is: (2*change - ans% (2*change)).  

3, Problem solving

1. Judge extreme situations

Using BFS here does not need to judge the extreme situation, and at least two nodes are transmitted.

2. Code implementation

class Solution {
public:
    int secondMinimum(int n, vector<vector<int>>& edges, int time, int change) {
        //Undirected graph is abstracted by zero order matrix 
        vector<vector<int>> Graphs(n+1);
        for(auto& item: edges){
            Graphs[item[0]].push_back(item[1]);
            Graphs[item[1]].push_back(item[0]);
        }
        // path[i][0] stores the shortest path length from the source point to node i, and path[i][1] stores the strict sub short path length from the source point to node I
        vector<vector<int>> path(n+1, vector<int>(2, INT_MAX));
        path[1][0] = 0;
        //The queue Q {i, J} is used to store the distance j from the source point to node i
        queue<pair<int, int>> Q;
        //Initialize BFS from node 1
        Q.push({1,0});
        //BFS is always used to calculate the minimum and sub small path from the source point to each node. When there is the sub small path of the destination node, the cycle stops
        while(path[n][1] == INT_MAX){
            //p is used to save the distance j from the source point to node i 
            auto p = Q.front();
            Q.pop();
            //bfsNode updates the minimum and secondary paths from the origin to the bfsNode node for the nodes reached in each round of breadth search
            for(auto bfsNode : Graphs[p.first]){
                //If the path from the source point to the bfsNode is less than the current minimum path, the minimum path is updated
                if(p.second + 1 < path[bfsNode][0]){
                    path[bfsNode][0] = p.second + 1;
                    Q.push({bfsNode, p.second + 1});
                }
                //If the path from the source point to the bfsNode is strictly larger than the minimum path and strictly smaller than the current minor path, the minor path will be updated
                if(p.second + 1 > path[bfsNode][0] && p.second + 1 < path[bfsNode][1]){
                    path[bfsNode][1] = p.second + 1;
                    Q.push({bfsNode, p.second + 1});
                }
            }
        }
        int ans = 0;
        //At the beginning, the light is green, and every 2*change is green again
        //Ans is the current total time ans% (2 * Change) > = change is the time to wait, and less than, there is no need to wait
        //(2 * Change - ans% (2 * Change)) is the waiting time
        for(int i = 0; i < path[n][1]; i++){
            if(ans % (2 * change) >= change){
                ans += (2 * change - ans % (2 * change));
            }
            ans += time;
        }
        return ans;
    }
};

4, Summary

At first, I was confused when I saw the problem (the foundation was relatively weak), and then I analyzed the problem solution step by step. At first, I didn't understand the meaning of pair parameters in the queue, and I pondered it for a long time. Later, I can imagine the undirected graph as a two-way graph. As long as I can't find the next short path, I will continue to BFS to increase the path length, Until the second short path is found.

The notes are very detailed. If there is any help for you, please click star ♥ Take a look, collect it, crab! 👇👇

Topics: C++ Algorithm data structure leetcode