๐ ๋ฐฑ์ค 2146๋ฒ ๋ค๋ฆฌ ๋ง๋ค๊ธฐ (BFS ํ์ด)
๐ ๋ฐฑ์ค 2146๋ฒ - ๋ค๋ฆฌ ๋ง๋ค๊ธฐ (BFS ํ์ด)
๐ 1. ๋ฌธ์ ์ค๋ช
NรN ํฌ๊ธฐ์ ์ง๋์์ ์ฌ๋ฌ ๊ฐ์ ์ฌ์ด ์กด์ฌํ๋ฉฐ,
๊ฐ ์ฌ์ ์ฐ๊ฒฐํ๋ ๊ฐ์ฅ ์งง์ ๋ค๋ฆฌ(0
์ผ๋ก๋ง ์ด๋ฃจ์ด์ง ๋ฐ๋ค)๋ฅผ ์ฐพ์์ผ ํฉ๋๋ค.
๋จ, ๋ค๋ฆฌ๋ ์ง์ ์ผ๋ก๋ง ์ฐ๊ฒฐ ๊ฐ๋ฅํ๊ณ , ๋๊ฐ์ ์ด๋์ ํ์ฉ๋์ง ์์ต๋๋ค.
๐ 2. ์ ๋ ฅ ๋ฐ ์ถ๋ ฅ ์์
๐น ์ ๋ ฅ ์์
10
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 1 1
1 1 0 0 0 0 0 0 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
1 1 1 0 0 0 0 1 1 1
๐น ์ถ๋ ฅ ์์
3
๐ ์ค๋ช
- ๊ฐ์ฅ ์งง์ ๋ค๋ฆฌ๋ ๊ธธ์ด๊ฐ
3
์ ๋๋ค.
๐ 3. ํด๊ฒฐ ๋ฐฉ๋ฒ (BFS)
์ด ๋ฌธ์ ๋ ์ต๋จ ๊ฑฐ๋ฆฌ ๋ฌธ์ ์ด๋ฏ๋ก
BFS(๋๋น ์ฐ์ ํ์, Breadth-First Search)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
๐น BFS๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ์์ด๋ฏ๋ก BFS๊ฐ ์ ํฉ
- DFS๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํด์ผ ํ๋ฏ๋ก ๋นํจ์จ์
- BFS๋ ๊ฐ ์ฌ์ ํ์ํ๋ฉด์ ๊ฐ์ฅ ์งง์ ๊ฑฐ๋ฆฌ์ ๋ค๋ฆฌ๋ฅผ ์ฐพ์ ์ ์์
๐ 4. ํต์ฌ ์ฝ๋ ๋ถ์
๐น ์ฌ์ ๊ตฌ๋ถํ๋ BFS (๊ฐ ์ฌ์ ๊ณ ์ ํ ๋ฒํธ ๋ถ์ฌ)
private static void markIsland(int x, int y, int islandNumber) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(x, y, 0, islandNumber));
visited[x][y] = true;
map[x][y] = islandNumber;
while (!q.isEmpty()) {
Point now = q.poll();
for (int i = 0; i < 4; i++) {
int nx = now.x + dX[i];
int ny = now.y + dY[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < N) {
if (!visited[nx][ny] && map[nx][ny] == 1) {
visited[nx][ny] = true;
map[nx][ny] = islandNumber;
q.offer(new Point(nx, ny, 0, islandNumber));
}
}
}
}
}
โ ์ค๋ช
markIsland()
๋ BFS๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ์ฌ์ ํ์ํ๋ฉฐislandNumber
๋ฅผ ํ ๋น- ๊ฐ์ ์ฌ์ ์ํ๋ ๋ชจ๋ ์ ์ ๊ฐ์ ๋ฒํธ๋ก ํ์
๐น ๋ค๋ฆฌ ์ฐพ๊ธฐ (BFS)
private static void findShortestBridge() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] > 1) { // ์ฌ์ด ์กด์ฌํ๋ ์์น๋ผ๋ฉด
boolean[][] visited = new boolean[N][N];
bfs(i, j, map[i][j], visited);
}
}
}
}
โ ์ค๋ช
findShortestBridge()
๋ ๋ชจ๋ ์ฌ์์ BFS ํ์์ ์ํํ์ฌ ์ต๋จ ๋ค๋ฆฌ๋ฅผ ์ฐพ์
๐น BFS๋ก ๋ค๋ฆฌ ๊ธธ์ด ๊ณ์ฐ
private static void bfs(int x, int y, int islandNumber, boolean[][] visited) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(x, y, 0, islandNumber));
visited[x][y] = true;
while (!q.isEmpty()) {
Point now = q.poll();
for (int i = 0; i < 4; i++) {
int nx = now.x + dX[i];
int ny = now.y + dY[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < N && !visited[nx][ny]) {
if (map[nx][ny] == 0) { // ๋ฐ๋ค์ธ ๊ฒฝ์ฐ
visited[nx][ny] = true;
q.offer(new Point(nx, ny, now.count + 1, islandNumber));
} else if (map[nx][ny] != islandNumber) { // ๋ค๋ฅธ ์ฌ์ ๋์ฐฉ
min = Math.min(min, now.count);
return;
}
}
}
}
}
โ ์ค๋ช
- BFS๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฆฌ๋ฅผ ํ์ฅํ๋ฉด์ ๊ฐ์ฅ ๋จผ์ ๋์ฐฉํ๋ ๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ๊ธฐ๋ก
- ๋ค๋ฅธ ์ฌ์ ๋์ฐฉํ๋ฉด ํ์ฌ
count
๊ฐ์min
๊ณผ ๋น๊ตํ์ฌ ์ต์๊ฐ์ ์ ์ฅ
๐ 5. ์ ์ฒด ์ฝ๋ (์ต์ข ์์ )
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Back_2146 {
static class Point {
int x, y, count, island;
public Point(int x, int y, int count, int island) {
this.x = x;
this.y = y;
this.count = count;
this.island = island;
}
}
static int[] dX = {0, 0, 1, -1};
static int[] dY = {1, -1, 0, 0};
static int[][] map;
static boolean[][] visited;
static int N, min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
// 1. ์
๋ ฅ ์ฒ๋ฆฌ
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
// 2. ์ฌ ๋ฒํธ ๋งค๊ธฐ๊ธฐ
int islandNumber = 2;
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] == 1 && !visited[i][j]) {
markIsland(i, j, islandNumber);
islandNumber++;
}
}
}
// 3. ์ต๋จ ๋ค๋ฆฌ ๊ธธ์ด ์ฐพ๊ธฐ
min = Integer.MAX_VALUE;
findShortestBridge();
// 4. ๊ฒฐ๊ณผ ์ถ๋ ฅ
System.out.println(min);
}
// BFS๋ก ์ฌ์ ๊ณ ์ ๋ฒํธ๋ฅผ ๋ถ์ฌ
private static void markIsland(int x, int y, int islandNumber) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(x, y, 0, islandNumber));
visited[x][y] = true;
map[x][y] = islandNumber;
while (!q.isEmpty()) {
Point now = q.poll();
for (int i = 0; i < 4; i++) {
int nx = now.x + dX[i];
int ny = now.y + dY[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < N) {
if (!visited[nx][ny] && map[nx][ny] == 1) {
visited[nx][ny] = true;
map[nx][ny] = islandNumber;
q.offer(new Point(nx, ny, 0, islandNumber));
}
}
}
}
}
// ์ต๋จ ๋ค๋ฆฌ ์ฐพ๊ธฐ (BFS)
private static void findShortestBridge() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] > 1) {
boolean[][] visited = new boolean[N][N];
bfs(i, j, map[i][j], visited);
}
}
}
}
// BFS๋ก ๋ค๋ฅธ ์ฌ๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ ์ฐพ๊ธฐ
private static void bfs(int x, int y, int islandNumber, boolean[][] visited) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(x, y, 0, islandNumber));
visited[x][y] = true;
while (!q.isEmpty()) {
Point now = q.poll();
for (int i = 0; i < 4; i++) {
int nx = now.x + dX[i];
int ny = now.y + dY[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < N && !visited[nx][ny]) {
if (map[nx][ny] == 0) {
visited[nx][ny] = true;
q.offer(new Point(nx, ny, now.count + 1, islandNumber));
} else if (map[nx][ny] != islandNumber) {
min = Math.min(min, now.count);
return;
}
}
}
}
}
}
๐ 6. ๊ฒฐ๋ก
๐ BFS๋ก ๊ฐ ์ฌ์ ํ์ํ์ฌ ๊ตฌ๋ถํ ํ, ์ต๋จ ๊ฑฐ๋ฆฌ์ ๋ค๋ฆฌ๋ฅผ ์ฐพ๋ ๋ฐฉ์์ผ๋ก ํด๊ฒฐ
๐ ์๊ฐ ๋ณต์ก๋: O(Nยฒ)
, ์ฆ N์ด ์ปค๋ ๋น ๋ฅด๊ฒ ์คํ ๊ฐ๋ฅ!
๐ฅ ์ด์ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ ๊ฒ์ด๋ฉฐ, ์ต๋จ ๊ฑฐ๋ฆฌ ๋ค๋ฆฌ๋ฅผ ์ฐพ์ ์ ์์!
๋๊ธ๋จ๊ธฐ๊ธฐ