【城市距离】题解

原题目链接:Link

题目描述

某个国家的地图可以看做是一个n*m的表格,单元格为’#‘表示城市区域,单元格为’.‘表示耕地区域。连通的’#'表示的区域是同一个城市。从一个单元格走到上下左右相邻的另一个单元格为一步。现在,你可以选择在任何一个城市的任何一个单元格中,请问你要走到其他的城市中去,最少要走多少步?

输入格式

第一行两个整数n和m。(1<=n,m<=500)

接下来有n行,每行一个字符串,有m个字符,每个字符要么是’#’,要么是’.’。

保证地图中至少有两个城市。

输出格式

最近两个城市的距离。

样例

样例输入

4 4
##…
…#
#…

样例输出

2

分析:

用两重循环遍历数组,每遇到一个‘#‘,就用dfs搜索,把它所在城市的所有’#‘变成’A’,顺便将这些位置入队列。再用bfs搜索,找到从当前位置到下一个城市的最短路。循环完之后,所有城市、所有路径都搜索完了。

需要特别注意细节的处理。

代码:

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int Maxn = 5e2 + 5;
const int zx[4] = {-1, 0, 1, 0}, zy[4] = {0, 1, 0, -1};
int n, m, ans = 1e6;
char c[Maxn][Maxn];
bool vis[Maxn][Maxn];
struct node {
	int x, y, step;
}; 
queue<node> q;
void dfs(int x, int y) {
	c[x][y] = 'A';
	q.push((node){x, y, 0});
	for(int i = 0;i < 4; ++i) {
		int dx = x + zx[i], dy = y + zy[i];
		if(dx >= 1 and dy >= 1 and dx <= n and dy <= m and c[dx][dy] == '#') dfs(dx, dy);
	}
}
void bfs() {
	memset(vis, 0, sizeof(vis));
	while(!q.empty()) {
		node p = q.front();
		q.pop();
		if(c[p.x][p.y] == '#') {
			ans = min(ans, p.step);
			while(!q.empty()) q.pop(); // 清空当前队列,不写89分 
			return ;
		}
		for(int i = 0;i < 4; ++i) {
			int dx = p.x + zx[i], dy = p.y + zy[i];
			if(dx >= 1 and dy >= 1 and dx <= n and dy <= m and !vis[dx][dy] and c[dx][dy] != 'A') {
				vis[dx][dy] = 1;
				q.push((node){dx, dy, p.step + 1});
			}
		}
	}
}
int main() {
	scanf("%d %d", &n, &m);
	for(int i = 1;i <= n; ++i) scanf("%s", c[i] + 1);
	for(int i = 1;i <= n; ++i)
		for(int j = 1;j <= m; ++j) {
			if(c[i][j] == '#') {
				dfs(i, j);
				bfs();
			} 
		}
	printf("%d", ans);
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值