BOJ 1719. 택배
1. 문제설명
N
개의 정점과M
개의 간선으로 이뤄진 그래프가 있다.-
어떤 정점에서 다른 정점으로 이동하기 위해 가장 먼저 거쳐야 하는 정점을 기록한 경로표를 출력하라
- 문제 분류
- Graph, Floyd
2. 알고리즘 설계
- 플로이드-워셜 경로 복원 문제이다.
- 문제의 그래프를 보면 무방향 그래프이다.
- 어떤 두 정점 간 간선이 1개이므로, 중복 처리는 안해도 된다.
next[u][v]
,next[v][u]
를 각각v
,u
로 처리해야 한다.
- 플로이드 값을 갱신할 때마다
next
배열의 값을 갱신한다. - 출력 관련
- 기존 코드에서는
cout << (i==j ? '-' : next[i][j])
로 했었다. - 근데 실제로 출력해보면 ‘-‘에 대한 아스키 코드 숫자가 출력된다.
- 그래서 아래 코드와 같이 if-else로 두 줄의 출력을 만들어줘야 한다.
- 기존 코드에서는
3. 전체 코드
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f, SZ = 202;
int n, m, D[SZ][SZ], nxt[SZ][SZ];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i=1; i<=n; i++) {
fill(D[i]+1, D[i]+n+1, INF);
D[i][i] = 0;
}
for(int u, v, c; m--;) {
cin >> u >> v >> c;
D[u][v] = D[v][u] = c;
nxt[u][v] = v;
nxt[v][u] = u;
}
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
if(D[i][j] > D[i][k]+D[k][j]) {
D[i][j] = D[i][k]+D[k][j];
nxt[i][j] = nxt[i][k];
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(i==j) cout << "- ";
else cout << nxt[i][j] << ' ';
}
cout << '\n';
}
return 0;
}