본문 바로가기

boj

백준 2146 다리 만들기

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

 

2146번: 다리 만들기

여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다

www.acmicpc.net

어제 이걸못풀어서  접을까 생각했다.

 

1. 일단, 모든 섬을 구분한다. (bfs1)

 

2. 섬의 가장자리(edge)좌표를 모두 구한다.

 

3. edge를 바탕으로 (bfs2) 를 진행하며, 바다를 그 섬으로 메워나간다

bridge배열을 만들어서, 메운 위치에 1씩 +하며 메운 점 갯수를 센다.

메워나가다가, 만일 자기 섬도 아니고 바다도 아닌 다른 섬을 만나면 이제 다리가 이어진것이다.

그러면 bridge의 현위치+만난위치가 경로이다.

 

여기서 한참을 헤멨는데,

당연히 먼져 도달한 것이 최소경로라고 생각했다. 하지만......

5

1 0 0 0 1

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 1 0 0 1

다음과같은 반례가 있다. 최소경로는 4,2   4,3 을 이은 2이지만,

문제는 먼져  왼쪽위와 오른쪽위가 디큐에 들어가므로, 맨 아랫쪽보다 먼져 만나게 된다.

그래서 answer과 만났을때의 합을 계속 비교하며, 최솟값을 찾는 식으로 풀었다.

다시풀으라고하면 또 잊어버려서 헤멜거같다.

 

 

import sys
input=sys.stdin.readline
from collections import deque
moves=[(-1,0),(1,0),(0,-1),(0,1)]
def bfs1(i,j,num): #섬클러스터링
    
    que=deque()
    arr[i][j]=num
    que.append((i,j))
    while que:
        i,j=que.popleft()
        
        for a,b in moves:
            tmp_i,tmp_j=i+a,j+b
            if 0<=tmp_i<n and 0<=tmp_j<n :
                if arr[tmp_i][tmp_j]==1:
                    arr[tmp_i][tmp_j]=num
                    que.append((tmp_i,tmp_j))

                elif arr[tmp_i][tmp_j]==0:
                    edge.append((i,j,num,0))
    return

def dfs2(): #다리놓기
    global answer
    queque=deque(edge)

    while queque:
        i,j,num,cnt=queque.popleft()
        for a,b in moves:
            tmp_i,tmp_j=i+a,j+b
            if 0<=tmp_i<n and 0<=tmp_j<n:
                if arr[tmp_i][tmp_j]==0:
                    arr[tmp_i][tmp_j]=num
                    brigde[tmp_i][tmp_j]=cnt+1
                    queque.append((tmp_i,tmp_j,num,cnt+1))
                
                elif arr[tmp_i][tmp_j]!=num:
                    answer=min(answer,cnt+brigde[tmp_i][tmp_j]) 
                    
                    

    

    




answer=1e+10
n=int(input())
arr=[ [* map (int,input().split())]for _ in range(n)]
brigde=[[False for _ in range(n)]for _ in range(n)]
num=2
edge=[]
for i in range(n):
    for j in range(n):
        if arr[i][j]==1:
            bfs1(i,j,num)
            num+=1
        else:
            continue
edge=list(set(edge))
dfs2()
print(answer)

'boj' 카테고리의 다른 글

백준 14226 이모티콘  (0) 2022.04.30
백준 13913 숨바꼭질4  (0) 2022.04.29
백준 16947 서울 지하철 2호선 (언젠간수정예정)  (0) 2022.04.28
벡준 16929 two dots  (0) 2022.04.26
백준 14500 테트로미노  (0) 2022.04.25