지도가 주어질 때, 가장 짧은 다리 하나를 놓아 두 대륙을 연결하는 방법을 찾으시오.
map
배열group
배열dist
배열1
들을 그룹화 하기 위해서는 DFS를 사용하는 방법이 있다.queue
에 넣고 상하좌우 한 칸씩 확장시킨다.0
이고, 확장할 떄마다 1
씩 증가한다.push
해주면 된다.#include <iostream>
#include <queue>
using namespace std;
static int N, map[100][100], group[100][100], dist[100][100];
static constexpr int d[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
inline bool isPossible(int y, int x) {
return (0 <= y && y < N) && (0 <= x && x < N);
}
void dfs(int y, int x, int g) {
group[y][x] = g;
for (int i = 0; i < 4; ++i) {
int ny = y + d[i][0], nx = x + d[i][1];
if (isPossible(ny, nx) && map[ny][nx] && group[ny][nx] != g) dfs(ny, nx, g);
}
}
void makeGroup() {
int g = 0;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x)
if (map[y][x] && group[y][x] == 0)
dfs(y, x, ++g);
}
void makeBridge() {
queue<pair<int, int>> q;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x) {
dist[y][x] = -1;
if (map[y][x]) {
q.push({y, x});
dist[y][x] = 0;
}
}
while (!q.empty()) {
int y = q.front().first, x = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i) {
int ny = y + d[i][0], nx = x + d[i][1];
if (isPossible(ny, nx) && dist[ny][nx] == -1) {
dist[ny][nx] = dist[y][x] + 1;
group[ny][nx] = group[y][x];
q.push({ny, nx});
}
}
}
}
int getAnswer() {
int ret = -1;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x)
for (int i = 0; i < 4; ++i) {
int ny = y + d[i][0], nx = x + d[i][1];
if (isPossible(ny, nx) && group[y][x] != group[ny][nx]) {
if (ret == -1) ret = dist[y][x] + dist[ny][nx];
else ret = min(ret, dist[y][x] + dist[ny][nx]);
}
}
return ret;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> N;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x)
cin >> map[y][x];
makeGroup();
makeBridge();
cout << getAnswer() << '\n';
}