카카오 코딩테스트에서 이 문제를 만났었다. 당시에도 플로이드 워셜 알고리즘의 존재를 알았지만 N:N shortest path를 O(N^3) 걸려 구하고 ?번을 바꿔가며 구한다는 게 마음에 안들어서 다익스트라로 접근하다가 풀기를 포기했던 문제이다. 하지만 플로이드 워셜의 O(N^3)은 상당히 빠르다.
N:N shortest path를 플로이드워셜 알고리즘으로 O(N^3) 걸려 구하고 ?번을 바꿔가며 O(N)걸려서 구한다
S, A, B를 포함한 1번~N번이 그 대상이다.
25분컷
#include <string>
#include <vector>
#include<iostream>
#include<math.h>
using namespace std;
int INF = 200*100000;
int tab[201][201];
void floyd(int n, vector<vector<int>> fares){
//배열 초기화
for(int i = 1;i<=n;i++){
for(int j =1;j<=n;j++){
tab[i][j] = INF;
if(i == j) tab[i][j] = 0;
}
}
//간선 반영
for(int ctr = 0;ctr<fares.size();ctr++){
int c = fares[ctr][0],d = fares[ctr][1],f = fares[ctr][2];
tab[c][d] = f;
tab[d][c] = f;
}
for(int k = 1;k<=n;k++){
for(int i = 1;i<=n;i++){
for(int j =1;j<=n;j++){
if(tab[i][k]+tab[k][j]<tab[i][j]){
tab[i][j] = tab[i][k]+tab[k][j];
}
}
}
}
}
int solution(int n, int s, int a, int b, vector<vector<int>> fares) {
int answer = 0;
floyd(n,fares);
int mind = INF*3;
for(int k = 1;k<=n;k++){
int d = tab[s][k]+tab[k][a]+tab[k][b];
mind = min(mind,d);
}
answer = mind;
return answer;
}