
https://www.acmicpc.net/problem/2146

어려워 보이지만, BFS를 조금만 활용하면 풀 수 있는 문제다.
#include <iostream>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
int N;
int cnt = 1;
int map[101][101];
bool visited[101][101];
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
void original_bfs(int x, int y, int cnt) {
	visited[x][y] = true;
	map[x][y] = cnt;
	queue<pair<int, int>> q;
	q.push({ x, y });
	
	while (!q.empty()) {
		int xx = q.front().first;
		int yy = q.front().second;
		q.pop();
		for (int i = 0; i < 4; i++) {
			int nx = xx + dx[i];
			int ny = yy + dy[i];
			if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && map[nx][ny] == -1) {
				q.push({ nx, ny });
				visited[nx][ny] = true;
				map[nx][ny] = cnt;
			}
		}
	}
}
int bfs(int num) {
	int distance = 0;
	queue<pair<int, int>> q;
	//육지에 있는 모든 땅 queue에 넣어주기
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (map[i][j] == num) {
				visited[i][j] = true;
				q.push({ i, j });
			}
		}
	}
	while (!q.empty()) {
		int Q_size = q.size();
		for (int i = 0; i < Q_size; i++) {
			int xx = q.front().first;
			int yy = q.front().second;
			q.pop();
			for (int j = 0; j < 4; j++) {
				int nx = xx + dx[j];
				int ny = yy + dy[j];
				if (nx >= 0 && nx < N && ny >= 0 && ny < N) {
					if (map[nx][ny] != 0 && map[nx][ny] != num) //바다 건너서 다른 육지에 도착
						return distance;
					else if (map[nx][ny] == 0 && !visited[nx][ny]) { //아직 방문하지 않은 바다
						q.push({ nx, ny });
						visited[nx][ny] = true;
					}
				}
			}
		}
		distance++;
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int ans = 1000000;
	cin >> N;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			int tmp;
			cin >> tmp;
			if (tmp == 1)
				map[i][j] = -1;
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (map[i][j] == -1) {
				original_bfs(i, j, cnt); //육지 번호 붙이기
				cnt++;
			}
		}
	}
	memset(visited, false, sizeof(visited));
	for (int i = 1; i < cnt; i++) {
		ans = min(ans, bfs(i));
		memset(visited, false, sizeof(visited));
	}
	cout << ans;
	return 0;
}