• acwing算法基础之搜索与图论--BFS


    1 基础知识

    BFS可以用来求取最短路,前提条件是所有边的权重一样。

    2 模板

    题目1:走迷宫,从左上角走到右下角,求最短路。

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 110;
    int d[N][N];
    int g[N][N];
    int n, m;
    
    int bfs() {
        memset(d, -1, sizeof d);
        
        queue<pair<int,int>> q;
        q.push({0,0});
        d[0][0] = 0;
        
        int dir[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
        
        while (!q.empty()) {
            auto t = q.front();
            q.pop();
            
            //t下一步可以走到哪儿
            for (int k = 0; k < 4; ++k) {
                int x = t.first + dir[k][0], y = t.second + dir[k][1];
                if (x >= n || x < 0 || y >= m || y < 0) continue;
                if (g[x][y] == 1) continue;
                if (d[x][y] != -1) continue;
                d[x][y] = d[t.first][t.second] + 1;
                q.push({x,y});
            }
        }
        
        return d[n-1][m-1];
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                cin >> g[i][j];
            }
        }
        
        cout << bfs() << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    扩展写法:输出最短路的路径。

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 110;
    int d[N][N];
    int g[N][N];
    int n, m;
    pair<int,int> before[N][N]; //存储前一个结点
    
    int bfs() {
        memset(d, -1, sizeof d);
        
        queue<pair<int,int>> q;
        q.push({0,0});
        d[0][0] = 0;
        
        int dir[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
        
        while (!q.empty()) {
            auto t = q.front();
            q.pop();
            
            //t下一步可以走到哪儿
            for (int k = 0; k < 4; ++k) {
                int x = t.first + dir[k][0], y = t.second + dir[k][1];
                if (x >= n || x < 0 || y >= m || y < 0) continue;
                if (g[x][y] == 1) continue;
                if (d[x][y] != -1) continue;
                d[x][y] = d[t.first][t.second] + 1;
                
                before[x][y] = t;
                
                q.push({x,y});
            }
        }
        
        //输出最短路的路径
        int i = n - 1, j = m - 1;
        while (i | j) {
            cout << "i = " << i << ", j = " << j << endl;
            pair<int,int> t = before[i][j];
            i = t.first;
            j = t.second;
        }
        
        return d[n-1][m-1];
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                cin >> g[i][j];
            }
        }
        
        cout << bfs() << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    题目2:八数码

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    int bfs(string start) {
        queue<string> q;
        q.push(start);
        
        unordered_map<string, int> d;
        d[start] = 0;
        
        string end = "12345678x";
        
        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
        
        while (!q.empty()) {
            string t = q.front();
            q.pop();
            
            if (t == end) {
                return d[t];
            }
            
            //t可以走到哪儿,可以走到new_t
            int idx = t.find('x');
            int i = idx / 3, j = idx % 3;
            for (int k = 0; k < 4; ++k) {
                int x = i + dirs[k][0], y = j + dirs[k][1];
                if (x < 0 || x >= 3 || y < 0 || y >= 3) continue;
                string new_t = t;
                swap(new_t[idx], new_t[x * 3 + y]);
                if (d.count(new_t)) continue;
                
                d[new_t] = d[t] + 1; //可以走到new_t
                q.push(new_t);
            }
        }
        
        return -1;
    }
    
    int main() {
        string start = "";
        char c;
        for (int i = 0; i < 9; ++i) {
            cin >> c;
            start += c;
        }
        
        cout << bfs(start) << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    3 工程化

    暂无。。。

  • 相关阅读:
    python查看自己安装的所有库并导出
    AGC059 A - My Last ABC Problem
    计算机毕业设计Java中华二十四节气文化传承宣展平台(源码+系统+mysql数据库+lw文档)
    戴尔R710服务器idrac安装centos7系统
    什么是自动采矿卡车autonomous mining trucks
    【开源分享】基于Html开发的房贷计算器,模仿新浪财经
    CSS基本介绍
    乐观锁和悲观锁区别
    互联网产品前后端分离测试(Eolink 分享)
    Golang Gocron开源定时框架
  • 原文地址:https://blog.csdn.net/YMWM_/article/details/134299134