문제출처: https://www.acmicpc.net/problem/2589


풀이

1.육지인 좌표에서 bfs를 돌리고

2. 그 좌표에서 bfs를 돌렸을 때 최단거리를 구함

3. 모든 육지좌표에서 1,2를 수행하며 최단거리 갱신

4. 마지막에 구한 최단거리==정답


핵심: 어떤 육지좌표에서 1,2를 수행하고 다른 육지좌표에서 최단거리를 구할 때 check배열은 0으로 초기화(방문하지않았다고)해야합니다.

그리고 정답을 출력할 때, 최단거리에서 1을 빼준값을 출력해야합니다. 아래 그림을 참조하면됩니다.

당연하지만, bfs가 아래 그림처럼 최단거리로 갱신해주기 때문에  최단거리문제에서 dfs보다 bfs가 훨씬유리합니다.



코드

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
char map[50][50];
int check[50][50];
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
int n, m;
int cnt;
int max_value = 0;
void bfs(int y, int x);
int main()
{
	cin.tie(0);
	cin.sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> map[i];
	
	//육지일때 그 좌표에서 최단거리구해봄
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (map[i][j] == 'L')
				//육지에서시작되는 각 좌표들로부터의 최단거리를
			{
				bfs(i, j);
				max_value = max(max_value, cnt);
				cnt = 0;
			}
		}
	}
	//육지에서 bfs를돌리면 그 육지의 좌표의 인접한 좌표가2가되므로 하나빼줘야됨
	cout << max_value-1 << '\n';
}
void bfs(int y, int x)
{
	//핵심! 육지인 모든곳을 탐색하므로 한번 탐색할때마다 갱신
	memset(check, 0, sizeof(check));
	queue<pair<int, int>>q;
	q.push({ y,x });
	check[y][x] = 1;
	while (!q.empty())
	{
		y = q.front().first;
		x = q.front().second;
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			int ny = y + dy[i];
			int nx = x + dx[i];
			//좌표범위내에서 확인
			if (nx >= 0 && ny >= 0 && nx < m && ny < n)
			{
				//만약 육지이고, 만나지않았떤길이면
				if (map[ny][nx] == 'L' && check[ny][nx] == 0)
				{
					check[ny][nx] = check[y][x] + 1;
					cnt = max(cnt, check[ny][nx]);
					q.push({ ny,nx });
				}
				
			}
		}
	}
}


결과


'문제풀이(BOJ) > DFS,BFS' 카테고리의 다른 글

[백준 1759] 암호 만들기  (0) 2020.02.06
[백준] 촌수계산  (0) 2020.01.20
[백준 14502] 연구소 (BFS)  (0) 2020.01.17
[백준 2667] 단지번호붙이기 (BFS)  (0) 2020.01.17
[백준 11724] 연결 요소의 개수(DFS)  (0) 2020.01.15

+ Recent posts