6366. 在网格图中访问一个格子的最少时间(dijkstra在矩阵上的运用)

简介: 6366. 在网格图中访问一个格子的最少时间(dijkstra在矩阵上的运用)

题目

思路

  • 首先,这是一个最短路问题
  • 直接用朴素记忆化搜索或者bfs无法实现“反复横跳”这一功能(只有有两个点以上可以走,就可以走到任意一个有最小时间限制的点)
  • 所以更换思维,用图论的方式思考
  • 每个点到上下左右有一条特殊的边,边权值为max(1,(grid[xx][yy]−dist[x][y])/2∗2+1)max( 1 , ( grid[ xx ][ yy ] - dist[ x ][ y ] ) / 2 * 2 + 1 )max(1,(grid[xx][yy]dist[x][y])/22+1),前者是一步的权值,后者是需要“反复横跳”才能走到的位置
  • 用堆优化dijkstra方法,因为最大的grid元素不超过1e5,所以堆中的元素是有限的,走的步数也是有限的
  • 当新的最短路径长度小于dist中对应点的大小,更新dist,然后入队
  • 教训:最短路问题都可以通过优化建边的技巧来解决┭┮﹏┭┮
  • 下面方法和题解的思路有一点不同,通过观察下标得到一个重要的结论:走到一个点的步数奇偶性和下标x+y的奇偶性相同
  • 其实都是一个道理,展现出来的面不同

代码

ini

复制代码

class Solution {
    struct node
    {
        int x,y,ti;
        bool operator < (const node & t)const{
            return ti > t.ti;
        }
    };
    
public:
    int minimumTime(vector<vector<int>>& grid) {
        if(grid[0][1] > 1 && grid[1][0] > 1)
        {
            return -1;
        }
        int n = grid.size(),m = grid[0].size();
        int dx[] = {0,1,0,-1},dy[] = {1,0,-1,0};
        vector<vector<int>> dist(n,vector<int>(m,1e9));
        dist[0][0] = 0;
        priority_queue<node> q;q.push({0,0,0});
        
        while(1){
            auto[x, y, d] = q.top();
            q.pop();
            if (x == n - 1 && y == m - 1)
                return d;
            for (int i = 0;i < 4;i ++) {
                int xx = x + dx[i],yy = y + dy[i];
                if (0 <= xx && xx < n && 0 <= yy && yy < m) {
                    int nd = max(d + 1, grid[xx][yy]);
                    nd += (nd - xx - yy) % 2;
                    if (nd < dist[xx][yy]) {
                        dist[xx][yy] = nd; // 更新最短路
                        q.push({xx,yy,nd});
                    }
                }
            }
        }
        return dist[n-1][m-1];
    }
};


相关文章
|
5天前
|
机器学习/深度学习 算法 测试技术
【数学】【网格】【状态压缩】782 变为棋盘
【数学】【网格】【状态压缩】782 变为棋盘
|
5天前
|
算法 测试技术 C#
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
|
5天前
leetcode-6110:网格图中递增路径的数目
leetcode-6110:网格图中递增路径的数目
23 1
|
5天前
|
机器学习/深度学习 存储 算法
C# | 凸包算法之Graham,快速找到一组点最外侧的凸多边形
这篇关于凸包算法的文章,本文使用C#和Graham算法来实现凸包算法。 首先消除两个最基本的问题: 什么是凸包呢? 凸包是一个包围一组点的凸多边形。凸多边形是指多边形中的每个内角都小于180度的多边形。 凸包算法有什么用呢? 凸包算法的作用是找到这个凸多边形,并且使用最少的点来绘制出它的轮廓。凸包算法在计算机图形学、计算几何和机器学习等领域中有着广泛的应用。
68 0
|
10月前
L2-023 图着色问题 (25 分)(图的遍历)
L2-023 图着色问题 (25 分)(图的遍历)
46 0
|
11月前
给定三个顶点的坐标使用程序计算三角形
给定三个顶点的坐标使用程序计算三角形
36 0
|
12月前
判断上三角矩阵
判断上三角矩阵 (15 分)
96 0
|
机器学习/深度学习
(模拟)(矩阵坐标表示)1219. 移动距离
(模拟)(矩阵坐标表示)1219. 移动距离
68 0
|
机器学习/深度学习
平面上有 n n个坐标相异的点,请问当中有多少组非共线的三个点,这三个点的 外心 也在这 nn 个点之中?
有一个正整数 nn 代表平面上的点数。 接下来有 nn 行,当中的第 ii 行包含两个整数 x_i, y_i,xi​,yi​ 代表第 i 个点的坐标是 (x_i, y_i)(xi​,yi​)。
86 0
7-1 顶点的度 (15 分)
7-1 顶点的度 (15 分)
207 0