https://www.acmicpc.net/problem/9694
9694번: 무엇을 아느냐가 아니라 누구를 아느냐가 문제다
맨위 첫 번째 줄에 T(1 <T< 100)는 테스트케이스 수를 의미한다. 이것을 따라 다음줄에 각 테스트 케이스가 주어지는데, 첫 번째 줄에는 N과 M이 주어진다. N(N ≤ 20)은 관계의 개수를 의미하며, M(5 ≤
www.acmicpc.net
간단한 최단경로 + 역추적 문제입니다. 제한이 작아서 매 테스트케이스마다 플로이드-워셜을 이용해 최단거리를 해주고 역추적으로 경로를 구하면 됩니다. 역추적은 정점 $i$에서 정점 $j$로 최단거리로 가는 길에 거쳐야 하는 정점을 기록해주고, 이를 기준으로 분할정복해서 구하면 됩니다.
아래는 코드입니다.
#include <bits/stdc++.h>
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
#define ends ' '
using namespace std;
int T, n, m, graph[22][22], memo[22][22];
vector<int> ans;
void trace(int s, int e) {
  if (memo[s][e] == -1) return;
  trace(s, memo[s][e]);
  ans.push_back(memo[s][e]);
  trace(memo[s][e], e);
}
int32_t main(void) {
  FastIO;
  T = 1;
  cin >> T;
  for (int _ = 1; _ <= T; _++) {
    cout << "Case #" << _ << ": ";
    cin >> n >> m;
    for (int i = 0; i < m; i++) for (int j = 0; j < m; j++) graph[i][j] = 987654321;
    memset(memo, -1, sizeof(memo));
    for (int i = 0; i < n; i++) {
      int a, b, x;
      cin >> a >> b >> x;
      graph[a][b] = x;
      graph[b][a] = x;
    }
    for (int k = 0; k < m; k++) {
      for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
          if (graph[i][k] + graph[k][j] < graph[i][j]) {
            graph[i][j] = graph[i][k] + graph[k][j];
            memo[i][j] = k;
          }
        }
      }
    }
    if (graph[0][m - 1] >= 987654321) {
      cout << -1 << endl;
      continue;
    }
    ans.clear();
    ans.push_back(0);
    trace(0, m - 1);
    ans.push_back(m - 1);
    for (auto x : ans) cout << x << ends;
    cout << endl;
  }
  return 0;
}'알고리즘 문제해결 > BOJ' 카테고리의 다른 글
| BOJ 2138 전구와 스위치 (0) | 2022.09.06 | 
|---|---|
| BOJ 4181 Convex Hull (0) | 2022.09.04 | 
| BOJ 20938 반짝반짝 (0) | 2022.09.02 | 
| BOJ 17308 Getting-Up Syndrome (0) | 2022.09.01 | 
| BOJ 25402 트리와 쿼리 (0) | 2022.08.31 |