Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

대웅짱님의 블로그

[2146] 다리 만들기 본문

알고리즘/BOJ

[2146] 다리 만들기

대웅짱 2018. 7. 4. 19:38

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


여러 개의 섬들을 잇는 다리중 가장 짧은 다리의 길이를 구하는 문제이다.


결국 문제를 해석하면 여러개의 컴포넌트가 주어지고 이 컴포넌트 사이의 가장 짧은 길이를 찾는 문제이다.


먼저 컴포넌트끼리의 구분을 지어야하기 때문에 DFS로 각 컴포넌트에 숫자를 부여했다.


그 후 최단 경로를 모든 섬 정점에서  BFS를 이용해 구하고 그 중 최솟값을 출력했다.


BFS를 수행할 때 각 섬들에게 번호를 부여하고 바다를 0 으로하여 만약 현재 정점의 섬 번호와 다른 섬 번호를 발견하면


거기서 BFS 종료를 시켜 현재 정점에서의 가장 가까운 섬까지의 거리를 계산하였다. 육지에서의 이동은 불 필요하므로


현재 보고있는 정점이 내 섬 번호와 같다면 더이상 진행하지 않고 바다일 때(0일 때)만 이동하게 했다.


문제 지문에서 알 수 있듯이 다리는 4방향으로 잇게 되므로 4방향 탐색으로 진행하면 된다.




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<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int n, cnt, mini;
int arr[110][110], land[110][110];
bool visit[110][110];
int dx[4= { 001-1 };
int dy[4= { 1-100 };
bool isPossible(int x, int y) {
    return x >= 0 && y >= 0 && x<n&&y<n;
}
 
void dfs(int x, int y) {
    visit[x][y] = 1;
    land[x][y] = cnt;
    for (int i = 0; i<4; i++) {
        int nx = dx[i] + x;
        int ny = dy[i] + y;
        if (isPossible(nx, ny) && !visit[nx][ny] && arr[nx][ny] == 1) {
            dfs(nx, ny);
        }
    }
}
 
int bfs(int x, int y, int color) {
    queue<pair<intint> > qu;
    qu.push({ x, y });
    visit[x][y] = 1;
    cnt = 0;
    while (int s = (int)qu.size()) {
        while (s--) {
            int cx = qu.front().first;
            int cy = qu.front().second;
            qu.pop();
            for (int i = 0; i<4; i++) {
                int nx = dx[i] + cx;
                int ny = dy[i] + cy;
                if (isPossible(nx, ny)) {
                    if (land[nx][ny] == color) continue;
                    if (land[nx][ny] != 0return cnt;
                    if (!visit[nx][ny]) {
                        visit[nx][ny] = 1;
                        qu.push({ nx, ny });
                    }
                }
            }
        }
        cnt++;
    }
    return 0;
}
 
 
int main() {
    scanf("%d"&n);
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            scanf("%d"&arr[i][j]);
        }
    }
    //dfs
    cnt = 1;
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            if (!visit[i][j] && arr[i][j] == 1) {
                dfs(i, j);
                cnt++;
            }
        }
    }
    //bfs
    mini = 987654321;
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            if (land[i][j] != 0) {
                memset(visit, 0sizeof(visit));
                int r = bfs(i, j, land[i][j]);
                if (r != 0) mini = min(mini, r);
            }
        }
    }
 
    printf("%d\n", mini);
 
    return 0;
}



'알고리즘 > BOJ' 카테고리의 다른 글

[4991] 로봇 청소기  (0) 2018.07.05
[5427] 불  (0) 2018.07.04
[5014] 스타트링크  (0) 2018.07.03
[9518] 로마 카톨릭 미사  (0) 2018.07.03
[9997] 폰트  (0) 2018.07.02