본문 바로가기

Algorithm/BFS

(C++) - 백준(BOJ) 11866번 : 다리만들기

반응형

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

 

2146번: 다리 만들기

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

www.acmicpc.net

풀이방법 : 섬마다 땅에 번호를 매긴 후 BFS를 이용해 원래섬에서 다른 섬까지의 거리의 최솟값을 구하면 답이됩니다.

 

Code :

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <algorithm>
#include <cstring>
#include <tuple>
#include <queue>
using namespace std;
 
int n,ans = 0x7f7f7f7f;
int dx[4= {0,0,-1,1};
int dy[4= {1,-1,0,0};
int mapOrigin[100][100];
int mapCopy[100][100];
int ck[100][100];
int islandCnt = 0;
 
void bfsDistance() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (mapCopy[i][j] != 0) {
                int areaNum = mapCopy[i][j];
                queue<tuple<intintint>> q;
                q.push({i, j, 1});
                ck[i][j] = 1;
                while (!q.empty()) {
                    auto pos = q.front(); 
                    q.pop();
                    int x = get<0>(pos);
                    int y = get<1>(pos);
                    int depth = get<2>(pos);
                    for (int k = 0; k < 4; k++) {
                        int nx = x + dx[k];
                        int ny = y + dy[k];
                        if (ny < 0 || nx < 0 || ny >= n || nx >= n) continue//n 범위 넘어갈 경우
                        if (mapCopy[nx][ny] == areaNum || ck[nx][ny] == 1continue//같은 섬인 경우
                        if (mapCopy[nx][ny] != 0 ) { //다른 섬에 도착했을 때
                            ans = min(ans, depth - 1);
                            while (!q.empty()) q.pop();
                            break;
                        }
                        ck[nx][ny] = 1;
                        q.push({nx, ny, depth + 1});
                    }
                }
                memset(ck, 0sizeof(ck));
            }
        }
    }
}
 
//섬 별로 번호를 메긴다.
void bfsCopy(){
    for(int i = 0 ;i <n; i++){
        for(int j = 0; j <n; j++){
            if(mapOrigin[i][j] && !ck[i][j]){
                islandCnt++;
                queue <pair<int,int>> q;
                q.push({i,j});
                ck[i][j] = 1;
                mapCopy[i][j] = islandCnt;
                while(!q.empty()){
                    int x = q.front().first;
                    int y = q.front().second;
                    q.pop();
                    for(int i = 0; i < 4; i++){
                        int nx = x + dx[i];
                        int ny = y + dy[i];
                        if(nx < 0 || nx >= n || ny < 0 || ny >= n)continue;
                        if(ck[nx][ny]==0 && mapOrigin[nx][ny]){
                            q.push({nx,ny});
                            ck[nx][ny] = 1;
                            mapCopy[nx][ny] = islandCnt;
                        }
                    }
                }
            }
        }
    }
}
 
int main(){
    cin >> n;
    for(int i = 0; i<n; i++)
        for(int j = 0 ; j < n; j++)
            cin >> mapOrigin[i][j];
    bfsCopy();
    bfsDistance();
    cout << ans <<'\n';
}

Test Case : 

Input :

5
1 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 0 1

output : 

1