티스토리 뷰

Algorithm

[백준 11562] 백양로 브레이크

devbelly 2020. 10. 29. 15:36

문제

www.acmicpc.net/problem/11562

 

알고리즘

floyd-warshall

 

풀이

$u$에서 $v$로 갈 때 필요한 최소한의 다리 설치 수를 묻고 있습니다.

 

플로이드-와샬의 특징은 모든 출발지와 도착지에 대해 최단거리를 구할 수 있습니다. 문제의 특징과 잘 맞으며 더군다나 $n$ 제한에서 플로이드-와샬임을 느낄 수 있습니다.

 

처음 모든 $dist$를 큰 값으로 초기화합니다. 만약 양방향 도로가 주어진다면 $dist[u][v]$, $dist [v][u]$를 0으로 설정합니다. 이는 각 정점에서 다른 정점으로 가기 위한 최소한의 다리 설치를 의미합니다. (단, 다리 설치는 단방향 다리에만 추가적으로 설치할 수 있습니다). 반면 단방향 도로가 주어진다면 연결되지 않은 곳만 1로 업데이트해주면 됩니다.

 

초기 셋팅을 위와 같이 하고 플로이드 와샬을 사용하면 배열의 값이 곧 최소한의 설치 수를 의미합니다. 시간 복잡도는 $O(N^3)$입니다.

 

코드

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
#define REP(i, n) for (int i = 1; i <= n; ++i)
using namespace std;

const int INF = 0x3f3f3f3f;

int n, m, u, v, t, q;
int dist[251][251];
int main() {
#ifndef ONLINE_JUDGE
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);

    memset(dist, 0x3f, sizeof(dist));
    cin >> n >> m;
    REP(i, n) dist[i][i] = 0;

    rep(i, m) {
        cin >> u >> v >> t;
        dist[u][v] = 0;
        if (t == 1)
            dist[v][u] = 0;
        else
            dist[v][u] = 1;
    }

    REP(k, n) REP(i, n) if (dist[i][k] != INF) REP(j, n) if (dist[k][j] != INF) {
        if (dist[i][j] > dist[i][k] + dist[k][j])
            dist[i][j] = dist[i][k] + dist[k][j];
    }
    cin >> q;
    while (q--) {
        cin >> u >> v;
        cout << dist[u][v] << '\n';
    }
    return 0;
}

'Algorithm' 카테고리의 다른 글

[백준 2091] 동전  (0) 2020.11.03
[백준 18879] The Moo Particle  (0) 2020.11.01
[백준 14932] 금고(SAFE)  (0) 2020.10.28
[백준 1744] 수 묶기  (0) 2020.10.27
[백준 18878] Cereal  (0) 2020.10.26
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   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
글 보관함