https://www.acmicpc.net/problem/2146
BFS를 2번 하여 문제를 풀었습니다.(섬카운트, 다리만들기)
먼저 섬마다 cnt를 줘서 1섬, 2섬, 3섬… 식으로 만든 후,(이또한 BFS)
BFS를 시작하기 전 섬의 끝에서 하기 위해 반복문을 사용했습니다.
반복문안에서 BFS로 들어가면 len배열을 통해 bfs를 해서 다리의 길이를 모두 체크했습니다.
마지막으로 다리 길이가 가장 작은 len을 result로 해줬습니다.
#include <iostream>
#include <queue>
using namespace std;
int map[101][101];
int len[101][101];//다리 카운트
int original[101][101];//ch배열 연산 후 다시 초기화하기 위해
bool tmpch[101][101];//섬마다 cnt하기위해 잠깐 쓰는 ch
queue <pair<int, int>> q;
int dx[] = { -1,0,1,0 };
int dy[] = { 0,-1,0,1 };
int result = 2000000000, n;
void bfs(int r, int c) {//다리길이를 bfs
q.push(make_pair(r, c));
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && ny >= 0 && nx < n&&ny < n) {
if (map[nx][ny] != map[r][c]&&map[nx][ny]!=0) {//다른 섬에 도착했을 때
result = result < len[x][y]-1 ? result : len[x][y]-1;
while (!q.empty()) q.pop();//큐를 모두 비워준다
return;
}
if (len[nx][ny] == false) {
len[nx][ny] = len[x][y]+1;
q.push(make_pair(nx, ny));
}
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
int tmp, cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> tmp;
map[i][j] = tmp;
len[i][j] = tmp;
original[i][j] = tmp;
}
}
for (int i = 0; i < n; i++) {//섬마다 cnt하기위한 bfs
for (int j = 0; j < n; j++) {
if (map[i][j] != 0 && tmpch[i][j] == false) {
cnt++;
map[i][j] = cnt;
tmpch[i][j] = true;//tmpch를 true로 줘서 4방향에 true 가 있으면 같은 섬으로 구분 짓기위해
q.push(make_pair(i, j));
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int k = 0; k < 4; k++) {
int nx = dx[k] + x;
int ny = dy[k] + y;
if (nx >= 0 && ny >= 0 && nx < n&&ny < n) {
if (map[nx][ny] != 0 && tmpch[nx][ny] == false) {
map[nx][ny] = cnt;
tmpch[nx][ny] = true;
q.push(make_pair(nx, ny));
}
}
}
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {//섬의 끝에서 다리를 짓기 위해 반복문 사용
if (map[i][j] != 0) {
for (int k = 0; k < 4; k++) {
int nx = dx[k] + i;
int ny = dy[k] + j;
if (nx >= 0 && ny >= 0 && nx < n&&ny < n) {
if (map[nx][ny] == 0) {
bfs(i, j);
for (int r = 0; r < n; r++) {
for (int t = 0; t < n; t++) {
len[r][t] = original[r][t];//ch다시 초기화
}
}
break;
//한번만 체크하면되니까 바로 break
}
}
}
}
}
}
cout << result << '\n';
}
- 혼잣말
예전에 풀어봤던 문제인데도 시간이 좀 걸렸다…(2시간..ㅠ)
오랜만에 제대로 풀어보는 BFS라 좀 까먹었던 것 같다.
덕분에 다시 BFS세포가 생겼다^^
처음에 섬을 카운트하는데 BFS말고 다른 방식을 찾으려다가 도저히 없는 것같아서
BFS를 썻다ㅋㅋㅋㅋㅋ;;;
시간이 많이 걸릴 것 같았는데 36ms밖에 안걸려서 살짝 좋았던ㅎㅎ