๐ŸŒ‰ ๋ฐฑ์ค€ 2146๋ฒˆ ๋‹ค๋ฆฌ ๋งŒ๋“ค๊ธฐ (BFS ํ’€์ด)

์—…๋ฐ์ดํŠธ:
5 ๋ถ„ ์†Œ์š”

๐ŸŒ‰ ๋ฐฑ์ค€ 2146๋ฒˆ - ๋‹ค๋ฆฌ ๋งŒ๋“ค๊ธฐ (BFS ํ’€์ด)

๋ฐฑ์ค€ ๋กœ๊ณ 


๐Ÿ“Œ 1. ๋ฌธ์ œ ์„ค๋ช…

Nร—N ํฌ๊ธฐ์˜ ์ง€๋„์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์„ฌ์ด ์กด์žฌํ•˜๋ฉฐ,
๊ฐ ์„ฌ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ์งง์€ ๋‹ค๋ฆฌ(0์œผ๋กœ๋งŒ ์ด๋ฃจ์–ด์ง„ ๋ฐ”๋‹ค)๋ฅผ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋‹จ, ๋‹ค๋ฆฌ๋Š” ์ง์„ ์œผ๋กœ๋งŒ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•˜๊ณ , ๋Œ€๊ฐ์„  ์ด๋™์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

alt alt


๐Ÿ“Œ 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์ด ์ปค๋„ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰ ๊ฐ€๋Šฅ!
๐Ÿ”ฅ ์ด์ œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•  ๊ฒƒ์ด๋ฉฐ, ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๋‹ค๋ฆฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Œ!

ํƒœ๊ทธ: , , , , , , , ,

์นดํ…Œ๊ณ ๋ฆฌ: ,

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ