网格最小代价路径,总代价不超过 budget

思路

普通 BFS 不能处理带权格子,Dijkstra 求的是最小代价,但这里多了 budget 限制。

如果只求最小代价,Dijkstra 可以;但要求"在不超过 budget 的前提下最小代价",其实仍然可以先求最小代价,再判断是否 ≤ budget。

不过因为可以上下左右走,且代价非负,所以可以用 Dijkstra。

如果代价可能为 0,Dijkstra 仍然适用。

如果要求"是否存在路径总代价 ≤ budget",也可以 Dijkstra 后判断。

代码

c

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define MAXM 205
#define MAXN 205
#define INF 0x3f3f3f3f

typedef struct {
    int x, y, dist;
} Node;

int m, n;
int cost[MAXM][MAXN];
int dist[MAXM][MAXN];
int visited[MAXM][MAXN];

int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

typedef struct {
    Node data[MAXM * MAXN * 4];
    int size;
} Heap;

void push(Heap *h, Node v) {
    int i = ++h->size;
    while (i > 1 && h->data[i / 2].dist > v.dist) {
        h->data[i] = h->data[i / 2];
        i /= 2;
    }
    h->data[i] = v;
}

Node pop(Heap *h) {
    Node res = h->data[1];
    Node last = h->data[h->size--];
    int i = 1, child;
    while (i * 2 <= h->size) {
        child = i * 2;
        if (child < h->size && h->data[child + 1].dist < h->data[child].dist)
            child++;
        if (last.dist <= h->data[child].dist) break;
        h->data[i] = h->data[child];
        i = child;
    }
    h->data[i] = last;
    return res;
}

int main() {
    int budget;
    scanf("%d %d", &m, &n);
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            scanf("%d", &cost[i][j]);
    scanf("%d", &budget);

    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            dist[i][j] = INF;

    Heap h;
    h.size = 0;

    dist[0][0] = cost[0][0];
    push(&h, (Node){0, 0, dist[0][0]});

    while (h.size > 0) {
        Node cur = pop(&h);
        int x = cur.x, y = cur.y;
        if (visited[x][y]) continue;
        visited[x][y] = 1;

        for (int k = 0; k < 4; k++) {
            int nx = x + dx[k];
            int ny = y + dy[k];
            if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
            int nd = cur.dist + cost[nx][ny];
            if (nd < dist[nx][ny]) {
                dist[nx][ny] = nd;
                push(&h, (Node){nx, ny, nd});
            }
        }
    }

    if (dist[m - 1][n - 1] <= budget)
        printf("%d\n", dist[m - 1][n - 1]);
    else
        printf("-1\n");

    return 0;
}
相关推荐
虚无的纽扣1 小时前
【力扣刷题】第五天:将 x 减到 0 的最小操作数、最大连续1的个数 III
算法·leetcode·职场和发展
C++ 老炮儿的技术栈1 小时前
char 造成的数据溢出
linux·服务器·c语言·c++·算法·c
sqc233sqc1 小时前
第 J8 周:ResNeXt-50 算法解析
人工智能·算法
hanlin0311 小时前
刷题笔记:力扣第32题-最长有效括号
笔记·算法·leetcode
All for pursuit.11 小时前
【动态规划-21】312.戳气球
数据结构·c++·算法·leetcode·动态规划
碧海银沙音频科技研究院14 小时前
基于炬芯ATS3089X自研AEC声学回声消除算法
算法
通问AI14 小时前
在两台 Mac Studio 上跑 800B 模型:MLX + RDMA over Thunderbolt 实测与四道门选型法
算法
ZywOo62314 小时前
《算法竞赛进阶指南》0x03 前缀和与差分
算法
Scintilla_y14 小时前
DAY2 滑动窗口
算法·leetcode·散列表