문제
https://www.acmicpc.net/problem/2146
풀이과정
단지번호붙이기와 토마토 문제를 합친 개념으로 보면 된다. 제한시간을 한시간으로 두고 풀어보려고 했지만 섬이 있는 곳들을 그룹으로 만드는거 이후 거리를 계산하는 방법이 떠오르지 않아서 검색을 통해 해결했다.
- 섬들을 그룹으로 묶어서 g 배열에 저장한다.
- 각 그룹마다 BFS를 통해 거리를 계산해 grup_dis 배열에 저장한다.
- 원래 입력값으로 저장되어있는 a 배열과 그룹으로 나누어 저장한 g 배열을 이용하여 현재 그룹의 아닌 다른 섬까지의 거리를 계산한다.
- 최소값을 출력한다.
3번 과정을 구현하는 소스코드를 보고도 이해하기 힘들었다. DFS, BFS 활용 문제는 정말 필수로 나오는 문제이니 관련 문제를 찾아서 더 많이 풀어봐야겠다.
소스코드
#include <iostream>
#include <queue>
using namespace std;
#define MAX 100
int a[MAX][MAX];
int g[MAX][MAX];
int grup_dis[MAX][MAX];
int group_max;
int dx[4] = { 0,0,-1,1 };
int dy[4] = { -1,1,0,0 };
int N;
bool chk(int x, int y)
{
return 0 <= x && x < N && 0 <= y && y < N;
}
void BFS()
{
int ans = -1;
for (int gpnum = 1; gpnum <= group_max; gpnum++)
{
queue<pair <int, int>> q;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
grup_dis[i][j] = -1;
if (g[i][j] == gpnum)
{
q.push(make_pair(i, j));
grup_dis[i][j] = 0;
}
}
}
while (!q.empty())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int k = 0; k < 4; k++)
{
int nx = x + dx[k];
int ny = y + dy[k];
if (chk(nx, ny))
{
if (grup_dis[nx][ny] == -1)
{
grup_dis[nx][ny] = grup_dis[x][y] + 1;
q.push(make_pair(nx, ny));
}
}
}
}
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (a[i][j] == 1 && g[i][j] != gpnum)
{
if (ans == -1 || grup_dis[i][j] - 1 < ans)
{
ans = grup_dis[i][j] - 1;
}
}
}
}
}
cout << ans;
}
void DFS(int x, int y, int cnt)
{
g[x][y] = cnt;
for (int k = 0; k < 4; k++)
{
int nx = x + dx[k];
int ny = y + dy[k];
if (chk(nx, ny))
{
if (a[nx][ny] == 1 && g[nx][ny] == 0)
{
DFS(nx, ny, cnt);
}
}
}
}
void Input()
{
cin >> N;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> a[i][j];
}
}
}
void divide_group()
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (a[i][j] == 1 && g[i][j] == 0)
{
DFS(i, j, ++group_max);
}
}
}
}
int main()
{
Input();
divide_group();
BFS();
return 0;
}