백준 2146. 다리 만들기

2025. 1. 22. 17:36·백준

https://www.acmicpc.net/problem/2146

import sys
from collections import deque
input = sys.stdin.readline

# 입력받기
N = int(input())
board = [list(map(int, input().split())) for _ in range(N)]

# 방향 벡터 (상, 하, 좌, 우)
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

# 섬 구분하기
def mark_islands():
    island_id = 2  # 섬의 ID는 2부터 시작
    for i in range(N):
        for j in range(N):
            if board[i][j] == 1:  # 아직 방문하지 않은 섬
                bfs_mark_island(i, j, island_id)
                island_id += 1

def bfs_mark_island(x, y, island_id):
    queue = deque([(x, y)])
    board[x][y] = island_id
    while queue:
        cx, cy = queue.popleft()
        for dx, dy in directions:
            nx, ny = cx + dx, cy + dy
            if 0 <= nx < N and 0 <= ny < N and board[nx][ny] == 1:
                board[nx][ny] = island_id
                queue.append((nx, ny))

# 다리 길이 계산
def find_shortest_bridge():
    shortest = float('inf')
    for i in range(N):
        for j in range(N):
            if board[i][j] > 1:  # 섬의 시작점
                shortest = min(shortest, bfs_shortest_bridge(i, j, board[i][j]))
    return shortest

def bfs_shortest_bridge(x, y, island_id):
    queue = deque([(x, y, 0)])  # 현재 위치와 거리
    visited = [[False] * N for _ in range(N)]
    visited[x][y] = True

    while queue:
        cx, cy, distance = queue.popleft()
        for dx, dy in directions:
            nx, ny = cx + dx, cy + dy
            if 0 <= nx < N and 0 <= ny < N and not visited[nx][ny]:
                visited[nx][ny] = True
                if board[nx][ny] == 0:  # 바다인 경우 계속 진행
                    queue.append((nx, ny, distance + 1))
                elif board[nx][ny] != island_id:  # 다른 섬에 도달한 경우
                    return distance
    return float('inf')  # 다른 섬에 도달하지 못한 경우

# 실행
mark_islands()  # 섬에 고유 ID 부여
result = find_shortest_bridge()  # 가장 짧은 다리 길이 계산
print(result)

[체크포인트]

1. board에서 1은 날것으로 두고 2부터 id를 매겨가면서 해당하는 모든 구역을 id로 바꿈 (bfs 이용)

2. 가장자리고 내부고 상관없이 섬의 모든 곳에서부터 시작해서 다른 섬으로 도달할 때까지 거리 매김(bfs 이용)

3. 그 거리를 매기는 함수에선 매번 돌릴 때마다 새로운 visitied 배열 이용(당연함.)

4. 거리 매길 때 다른 배열 만들지 않고 distance 변수를 추가해서 1씩 더해나감.

 

총 4개의 함수로 나누는 대장정을...그냥 감탄만 한다.

저작자표시 (새창열림)

'백준' 카테고리의 다른 글

백준 11559. Puyo Puyo  (0) 2025.01.23
백준 2206. 벽 부수고 이동하기  (0) 2025.01.23
백준 2583. 영역 구하기  (0) 2025.01.22
백준 3055. 탈출  (0) 2025.01.21
백준 1987. 알파벳  (0) 2025.01.21
'백준' 카테고리의 다른 글
  • 백준 11559. Puyo Puyo
  • 백준 2206. 벽 부수고 이동하기
  • 백준 2583. 영역 구하기
  • 백준 3055. 탈출
버그잡는고양이발
버그잡는고양이발
주니어 개발자입니다!
  • 버그잡는고양이발
    지극히평범한개발블로그
    버그잡는고양이발
  • 전체
    오늘
    어제
    • 분류 전체보기 (382)
      • React (16)
      • Next.js (5)
      • Javascript (5)
      • Typescript (4)
      • Node.js (2)
      • Cs (16)
      • 트러블 슈팅 (5)
      • Html (1)
      • Css (3)
      • Django (0)
      • vue (0)
      • Java (2)
      • Python (0)
      • 독서 (1)
      • 기타 (3)
      • 백준 (192)
      • swea (31)
      • 프로그래머스 (30)
      • 이코테 (4)
      • 99클럽 코테 스터디 (30)
      • ssafy (31)
      • IT기사 (1)
  • 블로그 메뉴

    • 홈
    • 태그
  • 인기 글

  • 태그

    코딩테스트준비
    99클럽
    Til
    항해99
    개발자취업
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
버그잡는고양이발
백준 2146. 다리 만들기
상단으로

티스토리툴바