当前位置:首页 > 洛谷 > 洛谷4554题解:BFS算法优化最短路径求解(附代码详解)

洛谷4554题解:BFS算法优化最短路径求解(附代码详解)

3个月前 (06-05)

洛谷4554题解:BFS算法优化最短路径求解(附代码详解)  广搜 BFS优化 最短路径 双向队列 双向队列优化 最短路径算法 第1张



一、题目解读

洛谷4554题要求在一个n×m的网格中,计算从点(x1,y1)到点(x2,y2)的最短路径距离。路径上的每个格子包含字符,若相邻格子字符不同,则需要额外步数。题目核心在于处理字符差异对路径长度的影响,并高效求解最短路径。

二、解题思路

采用广度优先搜索BFS算法,结合双向队列(deque)优化。关键思路:

    1. 初始化距离数组dist,标记所有点到起点距离为无穷;

    2. 使用双向队列存储待遍历节点:若相邻节点与当前节点字符相同,则插入队首(无需额外步数,优先扩展);若不同,则插入队尾(需额外步数);

    3. 通过四个方向遍历,动态更新最短距离,直至到达终点。

三、解题步骤

1. 数据预处理:将输入坐标转换为1-based索引(原代码中x1++,y1++,x2++,y2++实现);

2. BFS执行:

    起点入队,标记距离为0;

    循环弹出队首节点,遍历四周:

    判断边界和字符差异,计算移动成本(cost);

    若更新距离更优,则更新dist并调整入队位置(同字符入队首,异字符入队尾);

3. 终止条件:遍历至终点(x2,y2),返回其最短距离。

四、代码与注释

#include <iostream>
#include <deque>
#include <cstring>
using namespace std;

const int N = 510;  
char grid[N][N];  
int dist[N][N];  
int dx[] = {-1, 1, 0, 0};  // 方向偏移量  
int dy[] = {0, 0, -1, 1};
int n, m, x1, y1, x2, y2;

int bfs() {  
    // 初始化距离数组为无穷  
    memset(dist, 0x3f, sizeof dist);  
    deque<pair<int, int>> q;  
    q.push_back({x1, y1});  
    dist[x1][y1] = 0;  
    
    while (!q.empty()) {  
        auto t = q.front();  
        q.pop_front();  
        
        for (int i = 0; i < 4; i++) {  
            int nx = t.first + dx[i], ny = t.second + dy[i];  
            if (nx < 1 || nx > n || ny < 1 || ny > m) continue;  
            
            // 计算移动成本(字符不同需额外步数)  
            int cost = (grid[nx][ny]!= grid[t.first][t.second]);  
            if (dist[nx][ny] > dist[t.first][t.second] + cost) {  
                dist[nx][ny] = dist[t.first][t.second] + cost;  
                // 根据成本决定入队位置(优化关键)  
                if (cost == 0) q.push_front({nx, ny});  
                else q.push_back({nx, ny});  
            }  
        }  
    }  
    return dist[x2][y2];  
}

int main() {  
    while (cin >> n >> m, n || m) {  
        for (int i = 1; i <= n; i++)  
            for (int j = 1; j <= m; j++)  
                cin >> grid[i][j];  
        cin >> x1 >> y1 >> x2 >> y2;  
        x1++, y1++, x2++, y2++; // 转换为1-based索引  
        cout << bfs() << endl;  
    }  
    return 0;  
}

注释说明:

    1.双向队列通过区分插入位置实现分层遍历,减少冗余计算;

    2.字符差异判断(grid[nx][ny]!= grid[t.first][t.second])直接影响路径成本;

    3.坐标转换(索引+1)适配1-based题目要求。

五、总结

本解法通过BFS结合双向队列,巧妙利用字符状态优化搜索顺序,避免重复计算不同字符路径。核心在于根据移动成本动态调整入队策略,显著降低时间复杂度。掌握此类优化技巧对处理带条件约束的最短路径问题具有重要参考价值。



原创内容 转载请注明出处

分享给朋友:

相关文章

洛谷P2346四子连珠游戏最短步数BFS解法详解

洛谷P2346四子连珠游戏最短步数BFS解法详解

一、题目解读洛谷P2346是一道经典的棋盘游戏问题,要求在一4x4黑白棋棋盘上,通过移动棋子使同色棋子形成四子一线(横、竖或对角线),计算达成目标所需的最少步数。题目考察BFS算法应用和状态空间搜索能...

牛客13279题解:基于广度优先搜索(BFS)计算树高度的算法优化与代码实现

牛客13279题解:基于广度优先搜索(BFS)计算树高度的算法优化与代码实现

一、题目解读牛客13279题要求计算给定树的高度。树由n个节点组成,通过n-1条边连接,形成一棵有根树。题目核心在于高效求解树的高度,即从根节点到最深叶子节点的最长路径长度。需要理解树的结构特点,选择...

洛谷P1126机器人移动问题:基于BFS算法的解题方案与代码

洛谷P1126机器人移动问题:基于BFS算法的解题方案与代码

一、题目解读洛谷P1126题要求解决一个机器人移动问题:在一个n×m的网格中,机器人占用相邻的4个格子,初始位置和方向已知,需通过左转、右转、前进1-3步的指令到达终点。题目需判断是否存在路径,并输出...

牛客25438题解析:机器人移动可达点数量的BFS算法优化

牛客25438题解析:机器人移动可达点数量的BFS算法优化

一、题目解读牛客25438题要求计算在一个m行n列的网格中,从原点(0,0)出发,每次只能向上、下、左、右移动一步,且移动后的坐标各位数字之和不超过k的情况下,可达点的总数。题目考察对BFS(广度优先...

力扣1466题:利用BFS解决有向图重排问题

力扣1466题:利用BFS解决有向图重排问题

一、题目解读力扣1466题要求将一个有向图通过最小次数的“边重排”(即反转边方向)转化为一棵树。给定n个节点和m条边的有向图,需计算最少需要反转的边数,使图成为无环连通图(树)。题目需设计高效算法,避...

牛客12546题:广度优先搜索(BFS)解法解决饥饿的小易问题

牛客12546题:广度优先搜索(BFS)解法解决饥饿的小易问题

一、题目解读牛客12546题是一道典型的数学问题,要求通过给定的数学变换规则(即 x -> (4x+3) % MOD 和 x -> (8x+7) % MOD),从初始位置 x0 出发,寻找...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。