백준 1719 택배

치즈·2023년 1월 3일

BOJ

목록 보기
31/45

문제 출처 :
https://www.acmicpc.net/problem/1719

플로이드-와샬 알고리즘으로 풀면 되는 문제.업데이트될 때마다, 지나온 루트도 업데이트해주고, 마지막에 프린트할 때에만 루트의 1번째 값 출력해주면 된다.(0번째는 시작점, 마지막은 종착점)
이 때 주의할 점은 저 경로들이 양방향이라는 점이다.

#include <iostream>
#include <vector>
#define INF 9876543210
using namespace std;

int n, m;

long long dp[201][201];
vector<int> v[201][201];
long long Min(long long a, long long b) { return a < b ? a : b; }

void input() {
  cin >> n >> m;
  // init
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      dp[i][j] = INF;
      
      if (i == j)
        dp[i][j] = 0;
      // 자기 자신으로의 루트는 cost 0
      v[i][j].push_back(i);
      v[i][j].push_back(j);
      }
  }
  for (int i = 1; i <= m; i++) {
    int a, b, cost;
    cin >> a >> b >> cost;
    dp[a][b] = Min(cost, dp[a][b]);
    dp[b][a] = Min(cost, dp[b][a]);
  }
}

void floyd_Warshall() {
  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (dp[i][j] > dp[i][k] + dp[k][j]) {
          dp[i][j] = dp[i][k] + dp[k][j];
          vector<int> tmp = v[k][j];
          v[i][j].clear();
          v[i][j] = v[i][k];
          for(int l = 1; l < tmp.size(); l++){
            v[i][j].push_back(tmp[l]);
          }
        }
      }
    }
  }
}

void print_() {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (i == j)
        cout << "- ";
      else{
        cout << v[i][j][1] << " ";  
      }
    }
    cout << "\n";
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  input();
  floyd_Warshall();
  print_();
  return 0;
}

profile
차근차근 배워나가요

0개의 댓글