티스토리 뷰
문제
알고리즘
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
링크
TAG
- spring
- 2-SAT
- 세그먼트트리
- Fenwick
- knapsack
- Suffix Array
- hld
- 동적계획법
- greedy
- SCC
- DP
- 정렬
- 스위핑
- union find
- string
- kmp
- sweeping
- dfs
- 이분매칭
- spring boot
- 좌표압축
- implementation
- dijkstra
- bfs
- sorting
- 펜윅트리
- Segment tree
- 이분탐색
- Oracle
- 트라이
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함