zoukankan      html  css  js  c++  java
  • ACM:图的BFS,走迷宫

    题目:

    一个网格迷宫由n行m列的单元格组成,每一个单元格要么是空地(用1表示),要么是障碍物(用0来表示)。你的任务是找一条从起点到终点的最短移动序列,当中UDLR分别表示往上、下、左、右移动到相邻单元格。不论什么时候都不能在障碍格中。也不能走到迷宫之外。起点和终点保证是空地。


    分析:图的BFS。


    #include <iostream>
    #include <string>
    #include <queue>
    using namespace std;
    
    const int MAXN = 500;
    int maze[MAXN][MAXN], vis[MAXN][MAXN], dist[MAXN][MAXN], fa[MAXN][MAXN], last_dir[MAXN][MAXN];
    int n, m, xs, ys, xt, yt;
    
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    char name[] = "UDLR";
    
    void print_path(int x, int y) {      //以递归的方式打印路径
    	int fx = fa[x][y] / m;
        int fy = fa[x][y] % m;
        if(fx != x || fy != y) {
    		print_path(fx, fy);
    		putchar(name[last_dir[x][y]]);
        }
    }
    
    int dir[MAXN*MAXN];
    void print_path2(int x, int y) {      //以迭代的方式打印路径
    	int c = 0;
    	for(;;) {
    		int fx = fa[x][y] / m;
    		int fy = fa[x][y] % m;
    		if(fx == x && fy == y) break;
    		dir[c++] = last_dir[x][y];
    		x = fx;
     		y = fy;
    	}
    	while(c--) putchar(name[dir[c]]);
    }
    
    queue<int> q;
    void bfs(int x, int y) {
    	int u = x*m+y;
    	dist[x][y] = 0;   //初始化自己到自己的距离就是0
    	fa[x][y] = u;     //起点的父亲节点就是自己,方便后面的打印操作
    	vis[x][y] = 1;   
    	q.push(u);
    	while(!q.empty()) {
    		u = q.front();
    		q.pop();
    		x = u/m;
    		y = u%m;
    		for(int d = 0; d < 4; ++d) {
    			int nx = x + dx[d];
    			int ny = y + dy[d];
    			if(nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] && !vis[nx][ny]) {
    				int v = nx * m + ny;
    				q.push(v);
    				vis[nx][ny] = 1;
    				dist[nx][ny] = dist[x][y] + 1;    //走的步数+1
    				fa[nx][ny] = v;                   //记录父亲结点
    				last_dir[nx][ny] = d;             //记录如今这个节点到父亲节点走的方向
    			}
    		}
    	}
    }
    
    int main() {
    	cin >> n >> m >> xs >> ys >> xt >> yt;
    	for(int i = 0; i < n; ++i) {
    		for(int j = 0; j < m; ++j) {
    			cin >> maze[i][j];
    		}
    	}
    	memset(vis, 0, sizeof(vis));
    	bfs(xs, ys);
    	print_path(xt, yt);
    	cout << endl;
    	print_path2(xt, yt);
    	cout << endl;
    	return 0;
    }


  • 相关阅读:
    P1351 联合权值
    c++ 贪心讲解大礼包
    取石子 找规律
    树 dfs暴力判环 题意转化
    P2519 [HAOI2011]problem a
    P1640 [SCOI2010]连续攻击游戏 二分图最大匹配 匈牙利算法
    P2756 飞行员配对方案问题 二分图匹配 匈牙利算法
    cogs 49. 跳马问题 DFS dp
    cogs 2. 旅行计划 dijkstra+打印路径小技巧
    cogs 1440. [NOIP2013]积木大赛 贪心水题
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6702256.html
Copyright © 2011-2022 走看看