Leetcode 周赛记录:Second Minimum Time to Reach Destination

次短路径是盲区啊!比赛时硬是不知道,用DFS暴力超时,又看不懂BFS的解析

Description

A city is represented as a bi-directional connected graph with n vertices where each vertex is labeled from 1 to n (inclusive). The edges in the graph are represented as a 2D integer array edges, where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex ui and vertex vi. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself. The time taken to traverse any edge is time minutes.

Each vertex has a traffic signal which changes its color from green to red and vice versa every change minutes. All signals change at the same time. You can enter a vertex at any time, but can leave a vertex only when the signal is green. You cannot wait at a vertex if the signal is green.

The second minimum value is defined as the smallest value strictly larger than the minimum value.

  • For example the second minimum value of [2, 3, 4] is 3, and the second minimum value of [2, 2, 4] is 4.

Given n, edges, time, and change, return the second minimum time it will take to go from vertex 1 to vertex n.

Notes:

You can go through any vertex any number of times, including 1 and n.
You can assume that when the journey starts, all signals have just turned green.

在这里插入图片描述

Solution

  • 先考虑最短路径:最短路径上一定每个结点最多被访问一次

    • 否则可以将重复访问的结点删除
    • 这样就得到了一个更短的路径
  • 类似的针对于次短路径:次短路径上的每个结点最多被访问两次

    • 否则若存在结点访问大于等于3次,删去一次该结点-该结点的路径就得到了一条路径,于是这条路径才有可能称为次短路径
  • 下述代码层层推进

    • 不变量为每一层。出队为同层所有元素出队,入队为下一层元素入队
    • 因此队中元始终具有相同的时间
    • 因此外层循环每进行一次,搜索的路径长度加1
int secondMinimum(int n, vector<vector<int>>& edges, int time, int change) {
        //先中出单源最短路径
        vector<int> visited(n, 2);
        queue<int> q;
        vector<vector<int>> m(n, vector<int>());
        vector<int> log(n, -1);//防止节点重复添加

        //保存边
        for(auto edge: edges){
            m[edge[0] - 1].push_back(edge[1] - 1);
            m[edge[1] - 1].push_back(edge[0] - 1);
        }
        
        q.push(0);
        --visited[0];
        int t = 0;
        int first = -1;
        while (!q.empty()) {
            int qsize = q.size();
            if(t / change % 2 == 1)
                t += change - t % change;
            t += time;
            while (qsize-- > 0) {
                int idx = q.front();
                q.pop();
                for (int i = 0; i < m[idx].size(); ++i) {
                    if(t <= log[m[idx][i]] || visited[m[idx][i]] == 0)  //小于等于处意味着时间(也就是路径长)是和之前一样的,还要期待下一次再次遇到该结点
                        continue;
                    --visited[m[idx][i]];
                    log[m[idx][i]] = t;
                    q.push(m[idx][i]);
                    if (m[idx][i] == n - 1) {
                        if(first == -1){
                            first = t;
                            continue;
                        }
                        else
                            return t;
                    }
                }
            }
        }
        return 0;
    }

The K-shortest-path Problem

The k shortest path routing problem is a generalization of the shortest path routing problem in a given network. It asks not only about a shortest path but also about next k−1 shortest paths (which may be longer than the shortest path). A variation of the problem is the loopless k shortest paths.

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值