ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1602 - 도망자 원숭이
    Algorithm/BOJ 2020. 2. 14. 14:21
    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
    //1602 - 도망자 원숭이
     
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
     
    #define INF 200000000
     
    int N, M, C;
    vector<vector<int>> adj;
    vector<pair<intint>> ptime;
    vector<vector<int>> W;
     
    void init()
    {
        cin >> N >> M >> C;
        W = adj = vector<vector<int>>(N + 1vector<int>(N + 1, INF));
        ptime = vector<pair<intint>>(N);
        int x, y, r;
        for (int i = 0; i < N; ++i)
        {
            cin >> ptime[i].first;
            ptime[i].second = i + 1;
        }
        for (int i = 0; i < M; ++i)
        {
            cin >> x >> y >> r;
            adj[x][y] = adj[y][x] = r;
        }
        for(int i = 1; i<=N; ++i)
            adj[i][i] = 0;
        sort(ptime.begin(), ptime.end());
        for (int t = 0; t < N; ++t)
        {
            int k = ptime[t].second;
            for (int i = 1; i <= N; ++i)
                for (int j = 1; j <= N; ++j)
                {
                    if(k == i || k == j)
                        W[i][j] = adj[i][k] + adj[k][j] + ptime[t].first;
                    else
                    {
                        adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]);
                        W[i][j] = min(W[i][j], adj[i][k] + adj[k][j] + ptime[t].first);
                    }
                }
        }
    }
     
    int main()
    {
        ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        init();
        int x, y;
        for (int tn = 0; tn < C; ++tn)
        {
            cin >> x >> y;
            if(W[x][y] >= INF)
                cout << -1 << "\n";
            else
                cout << W[x][y] << "\n";
        }
    }
    cs

     

     

     

     

     

     

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

     

    1602번: 도망자 원숭이

    첫 번째 줄에는 도시의 개수 N (2 ≦ N ≦ 500) 과 도로의 개수 M (0 ≦ M ≦ 10,000), 그리고 질문의 개수 Q (0 ≦ Q ≦ 40,000) 가 주어진다. 그 다음 줄에, N개의 정수로 각 도시에서 멍멍이가 원숭이를 괴롭힐 수 있는 시간이 주어진다. 각 시간은 1이상 10,000이하의 정수이다. 그 후 M줄에 각각 3개의 정수로, 해당 도로가 잇는 두 도시의 번호 a, b (1 <= a, b <= N) 와 해당 도로의 통행시간 d 가

    www.acmicpc.net

     

     

     

     

     

     

    도망자 원숭이

    개는 경로의 정점중 가장 가중치가 큰 정점에 있습니다.

    즉 S -> T로 가는 경로는 개가 있는 정점과 가중치가 같거나 작은 정점들로만 이루어져 있습니다.(시작점, 끝점 제외)

    정점을 가중치의 오름차순으로 정렬하고 경유점으로 순서대로 플로이드 와샬 알고리즘을 사용하면, 모든 S -> T의 경로중 가장 가중치가 큰 정점에 개가 있는 모든 경로에 대해 구할 수 있습니다.

    시작점과 끝점이 경유점인 경우는 W[i][j]를 바로 갱신 시킵니다.

    (시작점과 끝점이 경유점이면 기존 경로가 바뀌지 않고, 또 정점은 가중치 오름차순 순으로 등장하기 때문에 W[i][j] 보다 adj[i][k] + adj[k][j] + weight[k]가 크더라도 갱신하는것이 타당합니다.)

     

     

     

     

     

     

    'Algorithm > BOJ' 카테고리의 다른 글

    집합 - 11723  (0) 2020.02.17
    제국 - 16402  (0) 2020.02.14
    파티 - 1238  (0) 2020.02.13
    비용 - 2463  (0) 2020.02.13
    학교 가지마! - 1420  (0) 2020.02.12

    댓글

Designed by Tistory.