网格最小代价路径,总代价不超过 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;
}
相关推荐
其实防守也摸鱼16 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
Nuanyt16 小时前
LeetCode Hot 100 链表专题(五)· 2 题(Java)
java·算法·leetcode·链表
w_zero_one19 小时前
递归算法(一)
java·开发语言·算法
风影同志7832421 小时前
20 个比特能装下多少行情?——实测拆解 Kronos 的 K 线分词器
算法
写的都是BUG21 小时前
APK 里的钥匙,一直就放在门口:聊聊加固真正该做什么
前端·算法
地平线开发者1 天前
CLIP 的零样本分类:一组文本如何变成图像分类器?
算法
京东云开发者1 天前
从“会生成”到“能生产”:萤火虫 AIGC 平台的 AI Infra 实践
算法·aigc·产品
youshi66681 天前
PID——算法改进
算法
一只不想敲代码的程序猿1 天前
如何更高效地拆解问题?
算法