ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [1939] 중량제한
    BOJ 2021. 9. 17. 10:04

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

     

    1939번: 중량제한

    첫째 줄에 N, M(1 ≤ M ≤ 100,000)이 주어진다. 다음 M개의 줄에는 다리에 대한 정보를 나타내는 세 정수 A, B(1 ≤ A, B ≤ N), C(1 ≤ C ≤ 1,000,000,000)가 주어진다. 이는 A번 섬과 B번 섬 사이에 중량제한이

    www.acmicpc.net

    <문제>

    양방향 그래프가 들어오고, 중량이 간선의 가중치보다 낮아야 이동이 가능할때 중량의 최대값을 구하는 문제다.

    가능한 중량C가 1~10억이여서 중량 C에 대해서 이분탐색을 진행해주어야 한다.

    bfs로 중량C에 대해서 정답의 가능성이 있는지를 판별한다. bool을 리턴하도록 구성해주었고

    true가 리턴되면 중량C를 운송이 가능하다는 의미이므로 left=mid+1을 진행한다.

    반대로 false가 리턴되면 중량을 줄여야하므로 right=mid-1을 진행한다.

    가능한 경우 10억에 대해 이분탐색을 진행하니 log2(10억)번정도 bfs가 호출되겠다.

     

    <소스코드>

    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
    #include<bits/stdc++.h>
    using namespace std;
    int n, m, s, e;
    bool _visit[10001];
    vector<pair<intint>>adj[10001];
    queue<int>q;
    bool bfs(int w) {
        memset(_visit, falsesizeof(_visit));
        while (!q.empty())q.pop();
        q.push(s);
        _visit[s] = true;
        while (!q.empty()) {
            int cur = q.front();
            q.pop();
            if (cur == e) {
                return true;
            }
            for (auto& x : adj[cur]) {
                if (x.second >= w && _visit[x.first] == false) {
                    q.push(x.first);
                    _visit[x.first] = true;
                }
            }
        }
        return false;
    }
    int main(void) {
        int i, left = 0, right = 0;
        scanf("%d %d"&n, &m);
        for (i = 0; i < m; i++) {
            int x, y, z;
            scanf("%d %d %d"&x, &y, &z);
            right = max(z, right);
            adj[x].push_back({ y,z });
            adj[y].push_back({ x,z });
        }
        scanf("%d %d"&s, &e);
        while (left <= right) {
            int mid = (left + right) / 2;
            if (bfs(mid) == true)left = mid + 1;
            else right = mid - 1;
        }
        printf("%d", right);
        return 0;
    }
    cs

     

     

    'BOJ' 카테고리의 다른 글

    [1937] 욕심쟁이 판다  (0) 2021.09.21
    [2003] 수들의 합 2  (0) 2021.09.19
    [14502] 연구소  (0) 2021.09.15
    [1759] 암호 만들기  (0) 2021.09.13
    [1197] 최소 스패닝 트리  (0) 2021.09.13

    댓글